tags. */ class Poem { /** * Bind the renderPoem function to the tag * @param Parser &$parser * @return bool true */ public static function init( &$parser ) { $parser->setHook( 'poem', [ 'Poem', 'renderPoem' ] ); return true; } /** * Parse the text into proper poem format * @param string $in The text inside the poem tag * @param array $param * @param Parser $parser * @param bool $frame * @return string */ public static function renderPoem( $in, $param = [], $parser = null, $frame = false ) { // using newlines in the text will cause the parser to add

tags, // which may not be desired in some cases $newline = isset( $param['compact'] ) ? '' : "\n"; $tag = $parser->insertStripItem( "
", $parser->mStripState ); // replace colons with indented spans $text = preg_replace_callback( '/^(:+)(.+)$/m', [ 'Poem', 'indentVerse' ], $in ); // replace newlines with
tags unless they are at the beginning or end // of the poem $text = preg_replace( [ "/^\n/", "/\n$/D", "/\n/" ], [ "", "", "$tag\n" ], $text ); // replace spaces at the beginning of a line with non-breaking spaces $text = preg_replace_callback( '/^( +)/m', [ 'Poem', 'replaceSpaces' ], $text ); $text = $parser->recursiveTagParse( $text, $frame ); $attribs = Sanitizer::validateTagAttributes( $param, 'div' ); // Wrap output in a

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 ) { $attribs = [ 'class' => 'mw-poem-indented', 'style' => 'display: inline-block; margin-left: ' . strlen( $m[1] ) . 'em;' ]; // @todo Should this really be raw? return Html::rawElement( 'span', $attribs, $m[2] ); } }