社区文档构建进行中,欢迎编辑。社区答疑群(非官方):717421103

全站通知:

帮助:解析函数/arrayprint

来自WIKI实验室WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索

Arrayprint是一个解析函数。帮助:解析函数页列出了所有解析函数的说明。

arrayprint

以指定的格式输出数组内容。出自扩展 Arrays BWIKI和各大Wiki平台广泛使用此扩展。<br>在遥远的未来,它可能与Mediawiki新的并行解析器不兼容,请参阅扩展主页了解更多信息。

它支持占位符替换、分隔符设置以及 wikitext 的嵌套解析(如模板、链接等)。

语法

{{#arrayprint: 数组名 | 分隔符 | 占位符 | 输出格式 | 选项 }}

  • 数组名: 指定要输出的数组。
  • 分隔符:用于分隔多个数组元素的字符串。默认为语言环境的顿号(如中文为 `、`)。支持 HTML 标签(如<br/>)。
  • 占位符:在输出wikitext中占位,每个元素会在占位符的位置输出
  • 输出格式:一段wikitext,定义单个数组元素的输出格式。需要包含占位符,否则将直接输出原始值。
  • 选项:支持print=pretty,将最后一个分隔符替换为

示例

先定义数组:{{#arraydefine:b|red, orange, blue}}

示例 效果
基本 {{#arrayprint:b}} red、orange、blue
无分隔符 {{#arrayprint:b | }} redorangeblue
以换行分隔 {{#arrayprint:b |<br/> }} red
orange
blue
wikitext示例 {{#arrayprint:b | <br/> | @ | @的长度:{{#len:@}} }} red的长度:3
orange的长度:6
blue的长度:4
wikitext示例 {{#arrayprint:b | <br/> | @ | {{Color| @ | @ }} }} red
orange
blue

底层代码

/** mediawiki-extensions-Arrays-REL1_37 ExtArrays.php
 * print an array.
 * foreach element of the array, print 'subject' where  all occurrences of 'search' is replaced with the element,
 * and each element print-out is deliminated by 'delimiter'
 * The subject can embed parser functions; wiki links; and templates.
 * usage:
 *      {{#arrayprint:arrayid|delimiter|search|subject|options}}
 * examples:
 *    {{#arrayprint:b}}    -- simple
 *    {{#arrayprint:b|<br/>}}    -- add change line
 *    {{#arrayprint:b|<br/>|@@@|[[@@@]]}}    -- embed wiki links
 *    {{#arrayprint:b|<br/>|@@@|{{#set:prop=@@@}} }}   -- embed parser function
 *    {{#arrayprint:b|<br/>|@@@|{{f.tag{{f.print.vbar}}prop{{f.print.vbar}}@@@}} }}   -- embed template function
 *    {{#arrayprint:b|<br/>|@@@|[[name::@@@]]}}   -- make SMW links
 */
public static function pfObj_arrayprint( Parser &$parser, PPFrame $frame, $args ) {
	global $egArraysCompatibilityMode, $egArraysExpansionEscapeTemplates;

	// Get Parameters
	$arrayId   = isset( $args[0] ) ? trim( $frame->expand( $args[0] ) ) : '';
	$delimiter = isset( $args[1] ) ? trim( $frame->expand( $args[1] ) ) : self::$mDefaultSep;
	/*
		* PPFrame::NO_ARGS and PPFrame::NO_TEMPLATES for expansion make a lot of sense here since the patterns getting replaced
		* in $subject before $subject is being parsed. So any template or argument influence in the patterns wouldn't make any
		* sense in any sane scenario.
		*/
	$search  = isset( $args[2] ) ? trim( $frame->expand( $args[2], PPFrame::NO_ARGS | PPFrame::NO_TEMPLATES ) ) : null;
	$subject = isset( $args[3] ) ? trim( $frame->expand( $args[3], PPFrame::NO_ARGS | PPFrame::NO_TEMPLATES ) ) : null;
	// options array:
	$options = isset( $args[4] )
			? self::parse_options( $frame->expand( $args[4] ) )
			: [];

	// get array, null if non-existant:
	$array = self::get( $parser )->getArray( $arrayId );

	if ( $array === null ) {
		// array we want to print doesn't exist!
		if ( !$egArraysCompatibilityMode ) {
			return '';
		} else {
			// COMPATIBILITY-MODE
			return "undefined array: $arrayId";
		}
	}

	// if there is no subject, there is no point in expanding. Faster!
	if ( $subject === null ) {
		if ( !$egArraysCompatibilityMode && $egArraysExpansionEscapeTemplates !== null ) {
			// we can ignore options here, since if subject is null, options won't be set as well!
			return trim( implode( $delimiter, $array ) );
		} else {
			// COMPATIBILITY-MODE
			// set search and subject so the old routine can be done
			$search = $subject = '@@@@';
		}
	}

	$rendered_values = [];

	foreach ( $array as $val ) {

		if ( !$egArraysCompatibilityMode ) {
			// NO COMPATIBILITY-MODE
			/**
			 * escape the array value so it won't destroy the users wiki markup expression.
			 */
			$val = self::escapeForExpansion( $val );
		}
		// replace place holder with current value:
		$rawResult = str_replace( $search, $val, $subject );
		/*
			* $subjectd still is un-expanded (this allows to use some parser functions like
			* {{FULLPAGENAME:@@@@}} directly without getting parsed before @@@@ is replaced.
			* Expand it so we replace templates like {{!}} which we need for the final parse.
			*/
		$rawResult = $parser->preprocessToDom( $rawResult, $frame->isTemplate() ? Parser::PTD_FOR_INCLUSION : 0 );
		$rawResult = trim( $frame->expand( $rawResult ) );

		$rendered_values[] = $rawResult;
	}

	// follow special print options:
	switch ( self::array_value( $options, 'print' ) ) {
		case 'pretty':
			// pretty list print with ' and ' connecting the last two items
			if ( $delimiter === '' ) {
				// '' as delimiter isn't pretty, so in this case we take the (languages) default
				$output = self::arrayToText( $rendered_values );
			} else {
				$output = self::arrayToText( $rendered_values, $delimiter );
			}
			break;

		default:
			// normal print with one delimiter, might be the languages default
			$output = implode( $delimiter, $rendered_values );
			break;
	}

	if ( $egArraysCompatibilityMode || $egArraysExpansionEscapeTemplates === null ) {
		// COMPATIBILITY-MODE:
		/*
			* don't leave the final parse to Parser::braceSubstitution() since there are some special cases where it
			* would produce unexpected output (it uses a new child frame and ignores whether the frame is a template!)
			*/
		$output = $parser->preprocessToDom( $output, $frame->isTemplate() ? Parser::PTD_FOR_INCLUSION : 0 );
		$output = $frame->expand( $output );
	}

	return trim( $output );
}

代码逻辑简述

  • 获取并验证数组:获取对应的数组。如果数组不存在,会根据兼容模式返回空字符串或错误信息。
  • 格式化输出:对数组的每个元素执行占位符替换,将指定的占位符(如 @@@)替换为数组值。展开Wikitext(用于使用模板、解析函数等)。
  • 处理选项:支持额外的输出选项,例如“pretty”模式(将数组元素以自然语言连接)。
  • 返回处理好的输出字符串