2012-06-29 20:49:13 +00:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* This class handles formatting poems in WikiText, specifically anything within
|
|
|
|
* <poem></poem> tags.
|
|
|
|
*/
|
|
|
|
class Poem {
|
|
|
|
/**
|
|
|
|
* Bind the renderPoem function to the <poem> tag
|
2017-08-10 11:23:22 +00:00
|
|
|
* @param Parser &$parser
|
2012-06-29 20:49:13 +00:00
|
|
|
* @return bool true
|
|
|
|
*/
|
|
|
|
public static function init( &$parser ) {
|
2017-05-18 16:26:55 +00:00
|
|
|
$parser->setHook( 'poem', [ 'Poem', 'renderPoem' ] );
|
2012-06-29 20:49:13 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Parse the text into proper poem format
|
|
|
|
* @param string $in The text inside the poem tag
|
|
|
|
* @param array $param
|
|
|
|
* @param Parser $parser
|
2017-08-10 11:23:22 +00:00
|
|
|
* @param bool $frame
|
2012-06-29 20:49:13 +00:00
|
|
|
* @return string
|
|
|
|
*/
|
2017-05-18 16:26:55 +00:00
|
|
|
public static function renderPoem( $in, $param = [], $parser = null, $frame = false ) {
|
2012-06-29 20:49:13 +00:00
|
|
|
// using newlines in the text will cause the parser to add <p> tags,
|
|
|
|
// which may not be desired in some cases
|
|
|
|
$newline = isset( $param['compact'] ) ? '' : "\n";
|
|
|
|
|
|
|
|
$tag = $parser->insertStripItem( "<br />", $parser->mStripState );
|
|
|
|
|
|
|
|
// replace colons with indented spans
|
2017-05-18 16:26:55 +00:00
|
|
|
$text = preg_replace_callback( '/^(:+)(.+)$/m', [ 'Poem', 'indentVerse' ], $in );
|
2012-06-29 20:49:13 +00:00
|
|
|
|
|
|
|
// replace newlines with <br /> tags unless they are at the beginning or end
|
|
|
|
// of the poem
|
|
|
|
$text = preg_replace(
|
2017-05-18 16:26:55 +00:00
|
|
|
[ "/^\n/", "/\n$/D", "/\n/" ],
|
|
|
|
[ "", "", "$tag\n" ],
|
2012-06-29 20:49:13 +00:00
|
|
|
$text );
|
|
|
|
|
|
|
|
// replace spaces at the beginning of a line with non-breaking spaces
|
2017-05-18 16:26:55 +00:00
|
|
|
$text = preg_replace_callback( '/^( +)/m', [ 'Poem', 'replaceSpaces' ], $text );
|
2012-06-29 20:49:13 +00:00
|
|
|
|
|
|
|
$text = $parser->recursiveTagParse( $text, $frame );
|
|
|
|
|
|
|
|
$attribs = Sanitizer::validateTagAttributes( $param, 'div' );
|
|
|
|
|
|
|
|
// Wrap output in a <div> with "poem" class.
|
|
|
|
if ( isset( $attribs['class'] ) ) {
|
|
|
|
$attribs['class'] = 'poem ' . $attribs['class'];
|
|
|
|
} else {
|
|
|
|
$attribs['class'] = 'poem';
|
|
|
|
}
|
|
|
|
|
|
|
|
return Html::rawElement( 'div', $attribs, $newline . trim( $text ) . $newline );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Callback for preg_replace_callback() that replaces spaces with non-breaking spaces
|
|
|
|
* @param array $m Matches from the regular expression
|
|
|
|
* - $m[1] consists of 1 or more spaces
|
|
|
|
* @return mixed
|
|
|
|
*/
|
|
|
|
protected static function replaceSpaces( $m ) {
|
|
|
|
return str_replace( ' ', ' ', $m[1] );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Callback for preg_replace_callback() that wraps content in an indented span
|
|
|
|
* @param array $m Matches from the regular expression
|
|
|
|
* - $m[1] consists of 1 or more colons
|
|
|
|
* - $m[2] consists of the text after the colons
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
protected static function indentVerse( $m ) {
|
2017-05-18 16:26:55 +00:00
|
|
|
$attribs = [
|
2012-06-29 20:49:13 +00:00
|
|
|
'class' => 'mw-poem-indented',
|
|
|
|
'style' => 'display: inline-block; margin-left: ' . strlen( $m[1] ) . 'em;'
|
2017-05-18 16:26:55 +00:00
|
|
|
];
|
2012-06-29 20:49:13 +00:00
|
|
|
// @todo Should this really be raw?
|
|
|
|
return Html::rawElement( 'span', $attribs, $m[2] );
|
|
|
|
}
|
|
|
|
}
|