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() );
+ }
+}