diff --git a/src/TexVC/MMLmappings/BaseMappings.php b/src/TexVC/MMLmappings/BaseMappings.php index 9c7886a63..04d95249f 100644 --- a/src/TexVC/MMLmappings/BaseMappings.php +++ b/src/TexVC/MMLmappings/BaseMappings.php @@ -483,12 +483,12 @@ class BaseMappings { "qquad" => [ 'spacer', 2 ], "thinspace" => [ 'spacer', MathSpace::THINMATHSPACE ], "negthinspace" => [ 'spacer', MathSpace::NEGATIVETHINMATHSPACE ], - "hskip" => 'Hskip', - "hspace" => 'Hskip', - "kern" => 'Hskip', - "mskip" => 'Hskip', - "mspace" => 'Hskip', - "mkern" => 'Hskip', + "hskip" => 'hskip', + "hspace" => 'hskip', + "kern" => 'hskip', + "mskip" => 'hskip', + "mspace" => 'hskip', + "mkern" => 'hskip', "rule" => 'rule', "Rule" => [ 'Rule' ], "Space" => [ 'Rule', 'blank' ], diff --git a/src/TexVC/MMLmappings/BaseParsing.php b/src/TexVC/MMLmappings/BaseParsing.php index c162afe8f..ae91a4351 100644 --- a/src/TexVC/MMLmappings/BaseParsing.php +++ b/src/TexVC/MMLmappings/BaseParsing.php @@ -346,11 +346,25 @@ class BaseParsing { return $mmlRow->encapsulateRaw( "HLINE TBD" ); } - public static function hskip( $node, $passedArgs, $operatorContent, $name, - $smth1 = null, $smth2 = null, $smth3 = null, $smth4 = null ) { - // tbd hskip - $mmlRow = new MMLmrow(); - return $mmlRow->encapsulateRaw( "hskip tbd" ); + public static function hskip( $node, $passedArgs, $operatorContent, $name ) { + if ( $node->getArg() instanceof Curly ) { + $unit = MMLutil::squashLitsToUnit( $node->getArg() ); + if ( !$unit ) { + return null; + } + $em = MMLutil::dimen2em( $unit ); + } else { + // Prevent parsing in unmapped cases + return null; + } + if ( $name == "mskip" || $name == "mkern" ) { + $args = [ "width" => $em ]; + } else { + return null; + } + + $mspace = new MMLmspace( "", $args ); + return $mspace->encapsulateRaw( "" ); } public static function handleOperatorName( $node, $passedArgs, $operatorContent, $name, diff --git a/src/TexVC/MMLmappings/Util/MMLutil.php b/src/TexVC/MMLmappings/Util/MMLutil.php index 6abe075be..a9866096b 100644 --- a/src/TexVC/MMLmappings/Util/MMLutil.php +++ b/src/TexVC/MMLmappings/Util/MMLutil.php @@ -2,6 +2,8 @@ namespace MediaWiki\Extension\Math\TexVC\MMLmappings\Util; use IntlChar; +use MediaWiki\Extension\Math\TexVC\Nodes\Curly; +use MediaWiki\Extension\Math\TexVC\Nodes\Literal; /** * Utility Methods for parsing Tex to MathML @@ -72,6 +74,47 @@ class MMLutil { return preg_replace( "/(\.\d\d\d).+/", '$1', $size ) . "em"; } + /** + * Assumes the input curly contains an TexArray of literals, squashes the TexArray characters to a string. + * @param Curly $node curly containing a TexArray of literals + * @return ?string squashed string in example "2mu", "-3mu" etc. Null if no TexArray inside curly. + */ + public static function squashLitsToUnit( Curly $node ): ?string { + $unit = ""; + foreach ( $node->getArg()->getArgs() as $literal ) { + if ( !$literal instanceof Literal ) { + continue; + } + $unit .= $literal->getArg(); + } + + return $unit; + } + + /** + * Convert a length dimension to em format + * currently supports "mu: math unit and forwards em" + * @param string $dimen input for length dimension like "-2mu" or "3 em" + * @return string|null converted string i.e. "0.333em" or null if error + */ + public static function dimen2em( string $dimen ): ?string { + $matches = []; + $matched = preg_match( '/([+-]?)(\d*\.*\d+)\s*(mu|em)/', $dimen, $matches ); + + if ( !$matched ) { + return null; + } + if ( $matches[3] == "mu" ) { + $ret = self::size2em( strval( intval( $matches[2] ) / 18 ) ); + } elseif ( $matches[3] == "em" ) { + $ret = $matches[2] . "em"; + } else { + return null; + } + + return ( $matches[1] == "-" ? "-" : "" ) . $ret; + } + /** * Some common steps of processing an input string before passing it as a key to the mappings. * @param string $input string to be processed diff --git a/tests/phpunit/unit/TexVC/Mhchem/MhchemBasicMMLTest.php b/tests/phpunit/unit/TexVC/Mhchem/MhchemBasicMMLTest.php new file mode 100644 index 000000000..140384bb3 --- /dev/null +++ b/tests/phpunit/unit/TexVC/Mhchem/MhchemBasicMMLTest.php @@ -0,0 +1,36 @@ + true, "usemhchemtexified" => true ]; + $warnings = []; + $checkRes = $texVC->check( $input, $options, $warnings, true ); + $this->assertStringContainsString( '', + $checkRes["input"]->renderMML() ); + } + + public function testMkern() { + $input = "\\ce{A, B}"; + $texVC = new TexVC(); + $options = [ "usemhchem" => true, "usemhchemtexified" => true ]; + $warnings = []; + $checkRes = $texVC->check( $input, $options, $warnings, true ); + $this->assertStringContainsString( '', + $checkRes["input"]->renderMML() ); + } +}