Page MenuHomeWickedGov Phorge

TexNode.php
No OneTemporary

Size
5 KB
Referenced Files
None
Subscribers
None

TexNode.php

<?php
declare( strict_types = 1 );
namespace MediaWiki\Extension\Math\WikiTexVC\Nodes;
use InvalidArgumentException;
use MediaWiki\Extension\Math\WikiTexVC\MMLmappings\BaseMethods;
class TexNode {
/** @var list<TexNode|string> */
protected $args;
/**
* Creates a TexNode
* @param TexNode|string ...$args arguments for this node
*/
public function __construct( ...$args ) {
foreach ( $args as $arg ) {
if ( !( $arg instanceof TexNode || is_string( $arg ) ) ) {
throw new InvalidArgumentException( 'Wrong input type specified in args.' );
}
}
$this->args = $args;
}
/**
* @param string $input
* @param array $passedArgs
* @param mixed|null $operatorContent
* @return string
*/
protected function parseToMML( $input, $passedArgs, $operatorContent ): string {
$parsed = BaseMethods::checkAndParse( $input, $passedArgs, $operatorContent, $this );
if ( $parsed ) {
return $parsed;
}
$name = strtoupper( self::class );
return BaseMethods::generateMMLError( "Not implemented $name for $input" );
}
/**
* @return TexNode[]|string[]
*/
public function getArgs(): array {
return $this->args;
}
/**
* @return string
*/
public function render() {
$out = '';
foreach ( $this->args as $child ) {
$out .= $child instanceof self ? $child->render() : $child;
}
return $out;
}
/**
* @param array $arguments
* @param array &$state
* @return string
*/
public function renderMML( $arguments = [], &$state = [] ) {
return array_reduce( $this->args, function ( $out, $child ) use ( $arguments, $state ) {
return $out . $this->renderChildMML( $child, $arguments, $state );
}, '' );
}
/**
* @param self|string $child
* @param array $arguments
* @param array &$state
* @return string
*/
public function renderChildMML( $child, $arguments, &$state ) {
if ( $child instanceof TexNode ) {
return $child->renderMML( $arguments, $state );
}
return $child;
}
/**
* @return bool
*/
public function isEmpty() {
foreach ( $this->args ?? [] as $arg ) {
if ( $arg instanceof TexNode && !$arg->isEmpty() ) {
return false;
}
if ( is_string( $arg ) && $arg !== '' ) {
return false;
}
}
return true;
}
public function getLength(): int {
return count( $this->args ?? [] );
}
/**
* Wraps the rendered result in curly brackets.
* @return string rendered result in curlies.
*/
public function inCurlies() {
return '{' . $this->render() . '}';
}
/**
* @param self[]|string[]|null $args
* @return string[]
*/
public function extractIdentifiers( $args = null ) {
$output = [];
foreach ( $args ?? $this->args as $value ) {
if ( $value instanceof self ) {
$output = array_merge( $output, $value->extractIdentifiers() );
} else {
$output[] = $value;
}
}
return $output;
}
/**
* @param string|array $target
* @param self[]|string[]|null $args
* @return bool
*/
public function containsFunc( $target, $args = null ) {
foreach ( $args ?? $this->args as $value ) {
if ( $value instanceof self ) {
$ret = $value->containsFunc( $target );
} else {
$ret = self::texContainsFunc( $target, $value );
}
if ( $ret ) {
// Do not check the other items, if some function has been found already.
return true;
}
}
return false;
}
/**
* @return string|array
*/
public function extractSubscripts() {
return [];
}
/**
* @return string|array
*/
public function getModIdent() {
return [];
}
/**
* strings can contain function references only in a few specific
* forms, which we test for here.
*
* @param string|array $target
* @param string $t Tex to be checked
* @return string|bool rendered LaTeX string or false if not found.
*/
public static function texContainsFunc( $target, string $t ) {
// protect against using random strings as keys in target
if ( !$t || $t[0] !== '\\' ) {
return false;
}
// may have trailing '(', '[', '\\{' or " "
$t = preg_replace( '/(\(|\[|\\\\{| )$/', '', $t );
// special case #1: \\operatorname {someword}
$m = preg_match( '/^\\\\operatorname \{([^\\\\]*)}$/', $t );
if ( $m == 1 ) {
return self::match( $target, '\\operatorname' );
}
// special case #2: \\mbox{\\somefunc}
$matches = [];
$m = preg_match( '/^\\\\mbox\{(\\\\.*)}$/', $t, $matches );
if ( $m == 1 ) {
return self::match( $target, '\\mbox' ) ?: self::match( $target, $matches[1] );
}
// special case #3: \\color, \\pagecolor, \\definecolor
$matches = [];
$m = preg_match( '/^(\\\\(?:page|define)?color) /', $t, $matches );
if ( $m == 1 ) {
return self::match( $target, $matches[1] );
}
// special case #4: \\mathbb, \\mathrm
$matches = [];
$m = preg_match( '/^(\\\\math..) \{(\\\\.*)}$/', $t, $matches );
if ( $m == 1 ) {
return self::match( $target, $matches[1] ) ?: self::match( $target, $matches[2] );
}
return self::match( $target, $t );
}
/**
* Matches a string against a string, array, or set target.
* @param string|array $target
* @param string $str
* @return bool|string matching value or false
*/
public static function match( $target, string $str ) {
if ( is_string( $target ) ) {
return $target === $str ? $str : false;
}
foreach ( $target as $key => $value ) {
// In javascript both types are used to comparison in match functionality
if ( is_string( $key ) ) {
if ( $key === $str ) {
return $str;
}
} elseif ( is_array( $value ) ) {
if ( self::match( $value, $str ) !== false ) {
return $str;
}
} elseif ( $value === $str ) {
return $str;
}
}
return false;
}
public function isCurly(): bool {
return false;
}
}

File Metadata

Mime Type
text/x-php
Expires
Aug 19 2026, 20:30 (7 w, 3 d ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
9f/a6/0fd09cb71ee9dad914eb375f58cd
Default Alt Text
TexNode.php (5 KB)

Event Timeline