2012-01-13 13:35:11 +00:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* Zend Framework
|
|
|
|
*
|
|
|
|
* LICENSE
|
|
|
|
*
|
|
|
|
* This source file is subject to the new BSD license that is bundled
|
|
|
|
* with this package in the file LICENSE.txt.
|
|
|
|
* It is also available through the world-wide-web at this URL:
|
|
|
|
* http://framework.zend.com/license/new-bsd
|
|
|
|
* If you did not receive a copy of the license and are unable to
|
|
|
|
* obtain it through the world-wide-web, please send an email
|
|
|
|
* to license@zend.com so we can send you a copy immediately.
|
|
|
|
*
|
|
|
|
* @category Zend
|
|
|
|
* @package Zend_Markup
|
|
|
|
* @subpackage Parser
|
2012-06-25 21:16:13 +00:00
|
|
|
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
|
2012-01-13 13:35:11 +00:00
|
|
|
* @license http://framework.zend.com/license/new-bsd New BSD License
|
2012-06-25 21:16:13 +00:00
|
|
|
* @version $Id: Textile.php 24594 2012-01-05 21:27:01Z matthew $
|
2012-01-13 13:35:11 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see Zend_Markup_TokenList
|
|
|
|
*/
|
|
|
|
require_once 'Zend/Markup/TokenList.php';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see Zend_Markup_Parser_ParserInterface
|
|
|
|
*/
|
|
|
|
require_once 'Zend/Markup/Parser/ParserInterface.php';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @category Zend
|
|
|
|
* @package Zend_Markup
|
|
|
|
* @subpackage Parser
|
2012-06-25 21:16:13 +00:00
|
|
|
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
|
2012-01-13 13:35:11 +00:00
|
|
|
* @license http://framework.zend.com/license/new-bsd New BSD License
|
|
|
|
*/
|
|
|
|
class Zend_Markup_Parser_Textile implements Zend_Markup_Parser_ParserInterface
|
|
|
|
{
|
|
|
|
|
|
|
|
const STATE_SCAN = 0;
|
|
|
|
const STATE_NEW_PARAGRAPH = 1;
|
|
|
|
const STATE_NEWLINE = 2;
|
|
|
|
|
|
|
|
const MATCH_ATTR_CLASSID = '\((?<attr_class>[a-zA-Z0-9_]+)?(?:\#(?<attr_id>[a-zA-Z0-9_]+))?\)';
|
|
|
|
const MATCH_ATTR_STYLE = "\{(?<attr_style>[^\}\n]+)\}";
|
|
|
|
const MATCH_ATTR_LANG = '\[(?<attr_lang>[a-zA-Z_]+)\]';
|
|
|
|
const MATCH_ATTR_ALIGN = '(?<attr_align>\<\>?|\>|=)';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Token tree
|
|
|
|
*
|
|
|
|
* @var Zend_Markup_TokenList
|
|
|
|
*/
|
|
|
|
protected $_tree;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Current token
|
|
|
|
*
|
|
|
|
* @var Zend_Markup_Token
|
|
|
|
*/
|
|
|
|
protected $_current;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Source to tokenize
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $_value = '';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Length of the value
|
|
|
|
*
|
|
|
|
* @var int
|
|
|
|
*/
|
|
|
|
protected $_valueLen = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Current pointer
|
|
|
|
*
|
|
|
|
* @var int
|
|
|
|
*/
|
|
|
|
protected $_pointer = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The buffer
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $_buffer = '';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Simple tag translation
|
|
|
|
*
|
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
protected $_simpleTags = array(
|
|
|
|
'*' => 'strong',
|
|
|
|
'**' => 'bold',
|
|
|
|
'_' => 'emphasized',
|
|
|
|
'__' => 'italic',
|
|
|
|
'??' => 'citation',
|
|
|
|
'-' => 'deleted',
|
|
|
|
'+' => 'insert',
|
|
|
|
'^' => 'superscript',
|
|
|
|
'~' => 'subscript',
|
|
|
|
'%' => 'span',
|
|
|
|
// these are a little more complicated
|
|
|
|
'@' => 'code',
|
|
|
|
'!' => 'img',
|
|
|
|
);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Token array
|
|
|
|
*
|
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
protected $_tokens = array();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Prepare the parsing of a Textile string, the real parsing is done in {@link _parse()}
|
|
|
|
*
|
|
|
|
* @param string $value
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
public function parse($value)
|
|
|
|
{
|
|
|
|
if (!is_string($value)) {
|
|
|
|
/**
|
|
|
|
* @see Zend_Markup_Parser_Exception
|
|
|
|
*/
|
|
|
|
require_once 'Zend/Markup/Parser/Exception.php';
|
|
|
|
throw new Zend_Markup_Parser_Exception('Value to parse should be a string.');
|
|
|
|
}
|
|
|
|
if (empty($value)) {
|
|
|
|
/**
|
|
|
|
* @see Zend_Markup_Parser_Exception
|
|
|
|
*/
|
|
|
|
require_once 'Zend/Markup/Parser/Exception.php';
|
|
|
|
throw new Zend_Markup_Parser_Exception('Value to parse cannot be left empty.');
|
|
|
|
}
|
|
|
|
|
|
|
|
// first make we only have LF newlines, also trim the value
|
|
|
|
$this->_value = str_replace(array("\r\n", "\r"), "\n", $value);
|
|
|
|
$this->_value = trim($this->_value);
|
|
|
|
|
|
|
|
// initialize variables and tokenize
|
|
|
|
$this->_valueLen = iconv_strlen($this->_value, 'UTF-8');
|
|
|
|
$this->_pointer = 0;
|
|
|
|
$this->_buffer = '';
|
|
|
|
$this->_temp = array();
|
|
|
|
$this->_tokens = array();
|
|
|
|
|
|
|
|
$this->_tokenize();
|
|
|
|
|
|
|
|
// create the tree
|
|
|
|
$this->_tree = new Zend_Markup_TokenList();
|
|
|
|
|
|
|
|
$this->_current = new Zend_Markup_Token('', Zend_Markup_Token::TYPE_NONE, 'Zend_Markup_Root');
|
|
|
|
$this->_tree->addChild($this->_current);
|
|
|
|
|
|
|
|
$this->_createTree();
|
|
|
|
|
|
|
|
return $this->_tree;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tokenize a textile string
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
protected function _tokenize()
|
|
|
|
{
|
|
|
|
$state = self::STATE_NEW_PARAGRAPH;
|
|
|
|
|
|
|
|
$attrsMatch = implode('|', array(
|
|
|
|
self::MATCH_ATTR_CLASSID,
|
|
|
|
self::MATCH_ATTR_STYLE,
|
|
|
|
self::MATCH_ATTR_LANG,
|
|
|
|
self::MATCH_ATTR_ALIGN
|
|
|
|
));
|
|
|
|
|
|
|
|
$paragraph = '';
|
|
|
|
|
|
|
|
while ($this->_pointer < $this->_valueLen) {
|
|
|
|
switch ($state) {
|
|
|
|
case self::STATE_SCAN:
|
|
|
|
$matches = array(); //[^\n*_?+~%@!-]
|
|
|
|
$acronym = '(?<acronym>[A-Z]{2,})\((?<title>[^\)]+)\)';
|
|
|
|
$regex = '#\G(?<text>.*?)(?:'
|
|
|
|
. "(?:(?<nl_paragraph>\n{2,})|(?<nl_break>\n))|"
|
|
|
|
. '(?<tag>'
|
|
|
|
. "(?<name>\*{1,2}|_{1,2}|\?{2}|\-|\+|\~|\^|%|@|!|$|{$acronym}"
|
|
|
|
. '|":(?<url>[^\s]+)|")'
|
|
|
|
. "(?:{$attrsMatch})*)"
|
|
|
|
. ')#si';
|
|
|
|
preg_match($regex, $this->_value, $matches, null, $this->_pointer);
|
|
|
|
|
|
|
|
$this->_pointer += strlen($matches[0]);
|
|
|
|
|
|
|
|
if (!empty($matches['text'])) {
|
|
|
|
$this->_buffer .= $matches['text'];
|
|
|
|
}
|
|
|
|
|
|
|
|
// first add the buffer
|
|
|
|
if (!empty($this->_buffer)) {
|
|
|
|
$this->_tokens[] = array(
|
|
|
|
'tag' => $this->_buffer,
|
|
|
|
'type' => Zend_Markup_Token::TYPE_NONE
|
|
|
|
);
|
|
|
|
$this->_buffer = '';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!empty($matches['nl_paragraph'])) {
|
|
|
|
$this->_temp = array(
|
|
|
|
'tag' => $matches['nl_paragraph'],
|
|
|
|
'name' => 'p',
|
|
|
|
'type' => Zend_Markup_Token::TYPE_TAG,
|
|
|
|
'attributes' => array()
|
|
|
|
);
|
|
|
|
|
|
|
|
$state = self::STATE_NEW_PARAGRAPH;
|
|
|
|
} elseif (!empty($matches['nl_break'])) {
|
|
|
|
$this->_tokens[] = array(
|
|
|
|
'tag' => $matches['nl_break'],
|
|
|
|
'name' => 'break',
|
|
|
|
'type' => Zend_Markup_Token::TYPE_TAG,
|
|
|
|
'attributes' => array()
|
|
|
|
);
|
|
|
|
|
|
|
|
$state = self::STATE_NEWLINE;
|
|
|
|
} elseif (!empty($matches['tag'])) {
|
|
|
|
if (isset($this->_simpleTags[$matches['name']])) {
|
|
|
|
// now add the new token
|
|
|
|
$this->_tokens[] = array(
|
|
|
|
'tag' => $matches['tag'],
|
|
|
|
'type' => Zend_Markup_Token::TYPE_TAG,
|
|
|
|
'name' => $this->_simpleTags[$matches['name']],
|
|
|
|
'attributes' => $this->_extractAttributes($matches)
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
$attributes = $this->_extractAttributes($matches);
|
|
|
|
if ($matches['tag'][0] == '"') {
|
|
|
|
$name = 'url';
|
|
|
|
if (isset($matches['url'])) {
|
|
|
|
$attributes['url'] = $matches['url'];
|
|
|
|
}
|
|
|
|
$this->_tokens[] = array(
|
|
|
|
'tag' => $matches['tag'],
|
|
|
|
'type' => Zend_Markup_Token::TYPE_TAG,
|
|
|
|
'name' => $name,
|
|
|
|
'attributes' => $attributes
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
$name = 'acronym';
|
|
|
|
$this->_tokens[] = array(
|
|
|
|
'tag' => '',
|
|
|
|
'type' => Zend_Markup_Token::TYPE_TAG,
|
|
|
|
'name' => 'acronym',
|
|
|
|
'attributes' => array(
|
|
|
|
'title' => $matches['title']
|
|
|
|
)
|
|
|
|
);
|
|
|
|
$this->_tokens[] = array(
|
|
|
|
'tag' => $matches['acronym'],
|
|
|
|
'type' => Zend_Markup_Token::TYPE_NONE
|
|
|
|
);
|
|
|
|
$this->_tokens[] = array(
|
|
|
|
'tag' => '(' . $matches['title'] . ')',
|
|
|
|
'type' => Zend_Markup_Token::TYPE_TAG,
|
|
|
|
'name' => 'acronym',
|
|
|
|
'attributes' => array()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$state = self::STATE_SCAN;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
case self::STATE_NEW_PARAGRAPH:
|
|
|
|
if (empty($this->_temp)) {
|
|
|
|
$this->_temp = array(
|
|
|
|
'tag' => '',
|
|
|
|
'name' => 'p',
|
|
|
|
'type' => Zend_Markup_Token::TYPE_TAG,
|
|
|
|
'attributes' => array()
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
$this->_tokens[] = array(
|
|
|
|
'tag' => "\n",
|
|
|
|
'name' => 'p',
|
|
|
|
'type' => Zend_Markup_Token::TYPE_TAG,
|
|
|
|
'attributes' => array()
|
|
|
|
);
|
|
|
|
$this->_temp['tag'] = substr($this->_temp['tag'], 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
$matches = array(); //[^\n*_?+~%@!-] (\()? [^()]+ (?(1)\))
|
|
|
|
$regex = "#\G(?<name>(h[1-6]|p)|(?:\#|\*))(?:{$attrsMatch})*(?(2)\.\s|\s)#i";
|
|
|
|
if (!preg_match($regex, $this->_value, $matches, null, $this->_pointer)) {
|
|
|
|
$this->_tokens[] = $this->_temp;
|
|
|
|
$state = self::STATE_SCAN;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->_pointer += strlen($matches[0]);
|
|
|
|
|
|
|
|
if ($matches['name'] == 'p') {
|
|
|
|
$this->_temp['tag'] .= $matches[0];
|
|
|
|
$this->_temp['attributes'] = $this->_extractAttributes($matches);
|
|
|
|
|
|
|
|
$this->_tokens[] = $this->_temp;
|
|
|
|
$this->_temp = array();
|
|
|
|
} else {
|
|
|
|
$this->_tokens[] = $this->_temp;
|
|
|
|
$this->_temp = array();
|
|
|
|
|
|
|
|
$name = $matches['name'];
|
|
|
|
$attributes = $this->_extractAttributes($matches);
|
|
|
|
|
|
|
|
if ($name == '#') {
|
|
|
|
$name = 'list';
|
|
|
|
$attributes['list'] = 'decimal';
|
|
|
|
} elseif ($name == '*') {
|
|
|
|
$name = 'list';
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->_tokens[] = array(
|
|
|
|
'tag' => $matches[0],
|
|
|
|
'name' => $name,
|
|
|
|
'type' => Zend_Markup_Token::TYPE_TAG,
|
|
|
|
'attributes' => $attributes
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
$state = self::STATE_SCAN;
|
|
|
|
break;
|
|
|
|
case self::STATE_NEWLINE:
|
|
|
|
$matches = array(); //[^\n*_?+~%@!-]
|
|
|
|
$regex = "#\G(?<name>(h[1-6])|(?:\#|\*))(?:{$attrsMatch})*(?(2)\.\s|\s)#si";
|
|
|
|
if (!preg_match($regex, $this->_value, $matches, null, $this->_pointer)) {
|
|
|
|
$state = self::STATE_SCAN;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->_pointer += strlen($matches[0]);
|
|
|
|
|
|
|
|
$name = $matches['name'];
|
|
|
|
$attributes = $this->_extractAttributes($matches);
|
|
|
|
|
|
|
|
if ($name == '#') {
|
|
|
|
$name = 'list';
|
|
|
|
$attributes['list'] = 'decimal';
|
|
|
|
} elseif ($name == '*') {
|
|
|
|
$name = 'list';
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->_tokens[] = array(
|
|
|
|
'tag' => $matches[0],
|
|
|
|
'name' => $name,
|
|
|
|
'type' => Zend_Markup_Token::TYPE_TAG,
|
|
|
|
'attributes' => $attributes
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a tree from the tokenized text
|
|
|
|
*
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
protected function _createTree()
|
|
|
|
{
|
|
|
|
$inside = true;
|
|
|
|
|
|
|
|
foreach ($this->_tokens as $key => $token) {
|
|
|
|
// first check if the token is a stopper
|
|
|
|
if ($this->_isStopper($token, $this->_current)) {
|
|
|
|
if ($this->_current->getName() == 'li') {
|
|
|
|
// list items are handled differently
|
|
|
|
if (isset($this->_tokens[$key + 1])
|
|
|
|
&& ($this->_tokens[$key + 1]['type'] == Zend_Markup_Token::TYPE_TAG)
|
|
|
|
&& ($this->_tokens[$key + 1]['name'] == 'list')
|
|
|
|
) {
|
|
|
|
// the next item is a correct tag
|
|
|
|
$this->_current->setStopper($token['tag']);
|
|
|
|
|
|
|
|
$this->_current = $this->_current->getParent();
|
|
|
|
} else {
|
|
|
|
// close the list
|
|
|
|
$this->_current->setStopper($token['tag']);
|
|
|
|
|
|
|
|
$this->_current = $this->_current->getParent()->getParent();
|
|
|
|
|
|
|
|
// go up in the tree until we found the end
|
|
|
|
while ($this->_isStopper($token, $this->_current)) {
|
|
|
|
$this->_current->setStopper($token['tag']);
|
|
|
|
|
|
|
|
$this->_current = $this->_current->getParent();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// go up in the tree until we found the end of stoppers
|
|
|
|
while ($this->_isStopper($token, $this->_current)) {
|
|
|
|
$this->_current->setStopper($token['tag']);
|
|
|
|
|
|
|
|
if (!empty($token['attributes'])) {
|
|
|
|
foreach ($token['attributes'] as $name => $value) {
|
|
|
|
$this->_current->addAttribute($name, $value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->_current = $this->_current->getParent();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$inside = true;
|
|
|
|
} elseif (($token['type'] == Zend_Markup_Token::TYPE_TAG) && $inside) {
|
|
|
|
if ($token['name'] == 'break') {
|
|
|
|
// add the newline and continue parsing
|
|
|
|
$this->_current->addChild(new Zend_Markup_Token(
|
|
|
|
$token['tag'],
|
|
|
|
Zend_Markup_Token::TYPE_NONE,
|
|
|
|
'',
|
|
|
|
array(),
|
|
|
|
$this->_current
|
|
|
|
));
|
|
|
|
} else {
|
|
|
|
// handle a list item
|
|
|
|
if ($token['name'] == 'list') {
|
|
|
|
$attributes = array();
|
|
|
|
if (isset($token['attributes']['list'])) {
|
|
|
|
$attributes['list'] = $token['attributes']['list'];
|
|
|
|
unset($token['attributes']['list']);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($this->_current->getName() != 'list') {
|
|
|
|
// the list isn't started yet, create it
|
|
|
|
$child = new Zend_Markup_Token(
|
|
|
|
'',
|
|
|
|
Zend_Markup_Token::TYPE_TAG,
|
|
|
|
'list',
|
|
|
|
$attributes,
|
|
|
|
$this->_current
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->_current->addChild($child);
|
|
|
|
|
|
|
|
$this->_current = $child;
|
|
|
|
}
|
|
|
|
$token['name'] = 'li';
|
|
|
|
} elseif (($token['name'] == 'img') || ($token['name'] == 'url')) {
|
|
|
|
$inside = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// add the token
|
|
|
|
$child = new Zend_Markup_Token(
|
|
|
|
$token['tag'],
|
|
|
|
Zend_Markup_Token::TYPE_TAG,
|
|
|
|
$token['name'],
|
|
|
|
$token['attributes'],
|
|
|
|
$this->_current
|
|
|
|
);
|
|
|
|
|
|
|
|
$this->_current->addChild($child);
|
|
|
|
|
|
|
|
$this->_current = $child;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// simply add the token as text
|
|
|
|
$this->_current->addChild(new Zend_Markup_Token(
|
|
|
|
$token['tag'],
|
|
|
|
Zend_Markup_Token::TYPE_NONE,
|
|
|
|
'',
|
|
|
|
array(),
|
|
|
|
$this->_current
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if a tag is a stopper
|
|
|
|
*
|
|
|
|
* @param array $token
|
|
|
|
* @param Zend_Markup_Token $current
|
|
|
|
*
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
protected function _isStopper(array $token, Zend_Markup_Token $current)
|
|
|
|
{
|
|
|
|
switch ($current->getName()) {
|
|
|
|
case 'h1':
|
|
|
|
case 'h2':
|
|
|
|
case 'h3':
|
|
|
|
case 'h4':
|
|
|
|
case 'h5':
|
|
|
|
case 'h6':
|
|
|
|
case 'list':
|
|
|
|
case 'li':
|
|
|
|
if (($token['type'] == Zend_Markup_Token::TYPE_TAG)
|
|
|
|
&& (($token['name'] == 'break') || ($token['name'] == 'p'))
|
|
|
|
) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'break':
|
|
|
|
return false;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (($token['type'] == Zend_Markup_Token::TYPE_TAG) && ($token['name'] == $current->getName())) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Extract the attributes
|
|
|
|
*
|
|
|
|
* @param array $matches
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
protected function _extractAttributes(array $matches)
|
|
|
|
{
|
|
|
|
$attributes = array();
|
|
|
|
|
|
|
|
if (!empty($matches['attr_class'])) {
|
|
|
|
$attributes['class'] = $matches['attr_class'];
|
|
|
|
}
|
|
|
|
if (!empty($matches['attr_id'])) {
|
|
|
|
$attributes['id'] = $matches['attr_id'];
|
|
|
|
}
|
|
|
|
if (!empty($matches['attr_style'])) {
|
|
|
|
$attributes['style'] = $matches['attr_style'];
|
|
|
|
}
|
|
|
|
if (!empty($matches['attr_lang'])) {
|
|
|
|
$attributes['lang'] = $matches['attr_lang'];
|
|
|
|
}
|
|
|
|
if (!empty($matches['attr_align'])) {
|
|
|
|
switch ($matches['attr_align']) {
|
|
|
|
case '=':
|
|
|
|
$attributes['align'] = 'center';
|
|
|
|
break;
|
|
|
|
case '>':
|
|
|
|
$attributes['align'] = 'right';
|
|
|
|
break;
|
|
|
|
case '<>':
|
|
|
|
$attributes['align'] = 'justify';
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
case '<':
|
|
|
|
$attributes['align'] = 'left';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $attributes;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|