woocommerce/apigen/libs/Texy/texy/modules/TexyBlockModule.php

230 lines
5.8 KiB
PHP

<?php
/**
* Texy! - human-readable text to HTML converter.
*
* @copyright Copyright (c) 2004, 2010 David Grudl
* @license GNU GENERAL PUBLIC LICENSE version 2 or 3
* @link http://texy.info
* @package Texy
*/
/**
* Special blocks module.
*
* @copyright Copyright (c) 2004, 2010 David Grudl
* @package Texy
*/
final class TexyBlockModule extends TexyModule
{
public function __construct($texy)
{
$this->texy = $texy;
//$texy->allowed['blocks'] = TRUE;
$texy->allowed['block/default'] = TRUE;
$texy->allowed['block/pre'] = TRUE;
$texy->allowed['block/code'] = TRUE;
$texy->allowed['block/html'] = TRUE;
$texy->allowed['block/text'] = TRUE;
$texy->allowed['block/texysource'] = TRUE;
$texy->allowed['block/comment'] = TRUE;
$texy->allowed['block/div'] = TRUE;
$texy->addHandler('block', array($this, 'solve'));
$texy->addHandler('beforeBlockParse', array($this, 'beforeBlockParse'));
$texy->registerBlockPattern(
array($this, 'pattern'),
'#^/--++ *+(.*)'.TEXY_MODIFIER_H.'?$((?:\n(?0)|\n.*+)*)(?:\n\\\\--.*$|\z)#mUi',
'blocks'
);
}
/**
* Single block pre-processing.
* @param TexyBlockParser
* @param string
* @return void
*/
public function beforeBlockParse($parser, & $text)
{
// autoclose exclusive blocks
$text = preg_replace(
'#^(/--++ *+(?!div|texysource).*)$((?:\n.*+)*?)(?:\n\\\\--.*$|(?=(\n/--.*$)))#mi',
"\$1\$2\n\\--",
$text
);
}
/**
* Callback for:.
* /-----code html .(title)[class]{style}
* ....
* ....
* \----
*
* @param TexyBlockParser
* @param array regexp matches
* @param string pattern name
* @return TexyHtml|string|FALSE
*/
public function pattern($parser, $matches)
{
list(, $mParam, $mMod, $mContent) = $matches;
// [1] => code | text | ...
// [2] => ... additional parameters
// [3] => .(title)[class]{style}<>
// [4] => ... content
$mod = new TexyModifier($mMod);
$parts = preg_split('#\s+#u', $mParam, 2);
$blocktype = empty($parts[0]) ? 'block/default' : 'block/' . $parts[0];
$param = empty($parts[1]) ? NULL : $parts[1];
return $this->texy->invokeAroundHandlers('block', $parser, array($blocktype, $mContent, $param, $mod));
}
// for backward compatibility
function outdent($s)
{
trigger_error('Use Texy::outdent()', E_USER_WARNING);
return Texy::outdent($s);
}
/**
* Finish invocation.
*
* @param TexyHandlerInvocation handler invocation
* @param string blocktype
* @param string content
* @param string additional parameter
* @param TexyModifier
* @return TexyHtml|string|FALSE
*/
public function solve($invocation, $blocktype, $s, $param, $mod)
{
$tx = $this->texy;
$parser = $invocation->parser;
if ($blocktype === 'block/texy') {
$el = TexyHtml::el();
$el->parseBlock($tx, $s, $parser->isIndented());
return $el;
}
if (empty($tx->allowed[$blocktype])) return FALSE;
if ($blocktype === 'block/texysource') {
$s = Texy::outdent($s);
if ($s==='') return "\n";
$el = TexyHtml::el();
if ($param === 'line') $el->parseLine($tx, $s);
else $el->parseBlock($tx, $s);
$s = $el->toHtml($tx);
$blocktype = 'block/code'; $param = 'html'; // to be continue (as block/code)
}
if ($blocktype === 'block/code') {
$s = Texy::outdent($s);
if ($s==='') return "\n";
$s = Texy::escapeHtml($s);
$s = $tx->protect($s, Texy::CONTENT_BLOCK);
$el = TexyHtml::el('pre');
$mod->decorate($tx, $el);
$el->attrs['class'][] = $param; // lang
$el->create('code', $s);
return $el;
}
if ($blocktype === 'block/default') {
$s = Texy::outdent($s);
if ($s==='') return "\n";
$el = TexyHtml::el('pre');
$mod->decorate($tx, $el);
$el->attrs['class'][] = $param; // lang
$s = Texy::escapeHtml($s);
$s = $tx->protect($s, Texy::CONTENT_BLOCK);
$el->setText($s);
return $el;
}
if ($blocktype === 'block/pre') {
$s = Texy::outdent($s);
if ($s==='') return "\n";
$el = TexyHtml::el('pre');
$mod->decorate($tx, $el);
$lineParser = new TexyLineParser($tx, $el);
// special mode - parse only html tags
$tmp = $lineParser->patterns;
$lineParser->patterns = array();
if (isset($tmp['html/tag'])) $lineParser->patterns['html/tag'] = $tmp['html/tag'];
if (isset($tmp['html/comment'])) $lineParser->patterns['html/comment'] = $tmp['html/comment'];
unset($tmp);
$lineParser->parse($s);
$s = $el->getText();
$s = Texy::unescapeHtml($s);
$s = Texy::escapeHtml($s);
$s = $tx->unprotect($s);
$s = $tx->protect($s, Texy::CONTENT_BLOCK);
$el->setText($s);
return $el;
}
if ($blocktype === 'block/html') {
$s = trim($s, "\n");
if ($s==='') return "\n";
$el = TexyHtml::el();
$lineParser = new TexyLineParser($tx, $el);
// special mode - parse only html tags
$tmp = $lineParser->patterns;
$lineParser->patterns = array();
if (isset($tmp['html/tag'])) $lineParser->patterns['html/tag'] = $tmp['html/tag'];
if (isset($tmp['html/comment'])) $lineParser->patterns['html/comment'] = $tmp['html/comment'];
unset($tmp);
$lineParser->parse($s);
$s = $el->getText();
$s = Texy::unescapeHtml($s);
$s = Texy::escapeHtml($s);
$s = $tx->unprotect($s);
return $tx->protect($s, Texy::CONTENT_BLOCK) . "\n";
}
if ($blocktype === 'block/text') {
$s = trim($s, "\n");
if ($s==='') return "\n";
$s = Texy::escapeHtml($s);
$s = str_replace("\n", TexyHtml::el('br')->startTag() , $s); // nl2br
return $tx->protect($s, Texy::CONTENT_BLOCK) . "\n";
}
if ($blocktype === 'block/comment') {
return "\n";
}
if ($blocktype === 'block/div') {
$s = Texy::outdent($s);
if ($s==='') return "\n";
$el = TexyHtml::el('div');
$mod->decorate($tx, $el);
$el->parseBlock($tx, $s, $parser->isIndented()); // TODO: INDENT or NORMAL ?
return $el;
}
return FALSE;
}
}