mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Math
synced 2024-11-27 17:01:07 +00:00
Add mathfraktur rendering for chrome
Chrome and similar browsers do not support the mathvariant attribute that can be used to change math fonts conveniently. Like for mathcal there is a table that can be used to translate from latin to mathfraktur chars. Bug: T378433 Change-Id: Id8c3e121ed104ba3f08329b4151a7e3bec699754
This commit is contained in:
parent
cc5c21dd54
commit
63b47f21ef
|
@ -788,12 +788,19 @@ class BaseParsing {
|
||||||
$state = [];
|
$state = [];
|
||||||
|
|
||||||
// Unicode fixes for the operators
|
// Unicode fixes for the operators
|
||||||
if ( $mathvariant == Variants::DOUBLESTRUCK ) {
|
switch ( $mathvariant ) {
|
||||||
$state = [ "double-struck-literals" => true ];
|
case Variants::DOUBLESTRUCK:
|
||||||
} elseif ( $mathvariant == Variants::CALLIGRAPHIC ) {
|
$state = [ "double-struck-literals" => true ];
|
||||||
$state = [ "calligraphic" => true ];
|
break;
|
||||||
} elseif ( $mathvariant == Variants::BOLDCALLIGRAPHIC ) {
|
case Variants::CALLIGRAPHIC:
|
||||||
$state = [ "bold-calligraphic" => true ];
|
$state = [ "calligraphic" => true ];
|
||||||
|
break;
|
||||||
|
case Variants::BOLDCALLIGRAPHIC:
|
||||||
|
$state = [ "bold-calligraphic" => true ];
|
||||||
|
break;
|
||||||
|
case Variants::FRAKTUR:
|
||||||
|
$state = [ "fraktur" => true ];
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $node instanceof Fun1nb ) {
|
if ( $node instanceof Fun1nb ) {
|
||||||
|
|
|
@ -149,6 +149,36 @@ class MMLParsingUtil {
|
||||||
return self::matchAlphanumeric( $inputString, $map );
|
return self::matchAlphanumeric( $inputString, $map );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function mapToFrakturUnicode( $inputString ): string {
|
||||||
|
$res = '';
|
||||||
|
$specialCases = [ 'C' => 'ℭ',
|
||||||
|
'H' => 'ℌ',
|
||||||
|
'I' => 'ℑ',
|
||||||
|
'R' => 'ℜ',
|
||||||
|
'Z' => 'ℤ' ];
|
||||||
|
foreach ( mb_str_split( $inputString ) as $chr ) {
|
||||||
|
// see https://www.w3.org/TR/mathml-core/#fraktur-mappings
|
||||||
|
if ( isset( $specialCases[$chr] ) ) {
|
||||||
|
$res .= $specialCases[$chr];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( $chr >= 'A' && $chr <= 'Z' ) {
|
||||||
|
$code = self::addToChr( $chr, '1D4C3' );
|
||||||
|
$res .= '&#x' . $code . ';';
|
||||||
|
} elseif ( $chr >= 'a' && $chr <= 'z' ) {
|
||||||
|
$code = self::addToChr( $chr, '1D4BD' );
|
||||||
|
$res .= '&#x' . $code . ';';
|
||||||
|
} else {
|
||||||
|
$res .= $chr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function addToChr( $chr, $base ): string {
|
||||||
|
return strtoupper( dechex( mb_ord( $chr ) + hexdec( $base ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
public static function matchAlphanumeric( $inputString, $map ) {
|
public static function matchAlphanumeric( $inputString, $map ) {
|
||||||
// Replace each character in the input string with its caligraphic Unicode equivalent
|
// Replace each character in the input string with its caligraphic Unicode equivalent
|
||||||
return preg_replace_callback( '/[A-Za-z0-9]/u', static function ( $matches ) use ( $map ) {
|
return preg_replace_callback( '/[A-Za-z0-9]/u', static function ( $matches ) use ( $map ) {
|
||||||
|
|
|
@ -34,7 +34,7 @@ class Literal extends TexNode {
|
||||||
|
|
||||||
public function changeUnicodeFontInput( $input, $state ) {
|
public function changeUnicodeFontInput( $input, $state ) {
|
||||||
/**
|
/**
|
||||||
* In some font modifications, it is required to explicitly use unicode
|
* In some font modifications, it is required to explicitly use Unicode
|
||||||
* characters instead of (only) attributes in MathML to indicate the font.
|
* characters instead of (only) attributes in MathML to indicate the font.
|
||||||
* This is mostly because of Chrome behaviour. I.e. see: https://phabricator.wikimedia.org/T352196
|
* This is mostly because of Chrome behaviour. I.e. see: https://phabricator.wikimedia.org/T352196
|
||||||
*/
|
*/
|
||||||
|
@ -42,6 +42,8 @@ class Literal extends TexNode {
|
||||||
return MMLParsingUtil::mapToDoubleStruckUnicode( $input );
|
return MMLParsingUtil::mapToDoubleStruckUnicode( $input );
|
||||||
} elseif ( isset( $state["calligraphic"] ) ) {
|
} elseif ( isset( $state["calligraphic"] ) ) {
|
||||||
return MMLParsingUtil::mapToCaligraphicUnicode( $input );
|
return MMLParsingUtil::mapToCaligraphicUnicode( $input );
|
||||||
|
} elseif ( isset( $state["fraktur"] ) ) {
|
||||||
|
return MMLParsingUtil::mapToFrakturUnicode( $input );
|
||||||
}
|
}
|
||||||
return $input;
|
return $input;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,16 @@ use MediaWikiUnitTestCase;
|
||||||
* @covers \MediaWiki\Extension\Math\WikiTexVC\TexVC
|
* @covers \MediaWiki\Extension\Math\WikiTexVC\TexVC
|
||||||
*/
|
*/
|
||||||
class MMLRenderTest extends MediaWikiUnitTestCase {
|
class MMLRenderTest extends MediaWikiUnitTestCase {
|
||||||
|
|
||||||
|
public function testMathFRakUnicode() {
|
||||||
|
$input = "\\mathfrak{O}, \\mathfrak{K}, \\mathfrak{t}, \\mathfrak{C}";
|
||||||
|
$mathMLtexVC = $this->generateMML( $input );
|
||||||
|
$this->assertStringContainsString( '𝔒', $mathMLtexVC );
|
||||||
|
$this->assertStringContainsString( '𝔎', $mathMLtexVC );
|
||||||
|
$this->assertStringContainsString( '𝔱', $mathMLtexVC );
|
||||||
|
$this->assertStringContainsString( 'ℭ', $mathMLtexVC );
|
||||||
|
}
|
||||||
|
|
||||||
public function testMathCalUnicode() {
|
public function testMathCalUnicode() {
|
||||||
$input = "\\mathcal{O}, \\mathcal{K}, \\mathcal{t}, \\mathcal{c}";
|
$input = "\\mathcal{O}, \\mathcal{K}, \\mathcal{t}, \\mathcal{c}";
|
||||||
$mathMLtexVC = $this->generateMML( $input );
|
$mathMLtexVC = $this->generateMML( $input );
|
||||||
|
|
|
@ -29,4 +29,23 @@ class MMLParsingUtilTest extends MediaWikiUnitTestCase {
|
||||||
$this->assertNull( $result );
|
$this->assertNull( $result );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testUnicode_afr() {
|
||||||
|
$result = MMLParsingUtil::mapToFrakturUnicode( 'a' );
|
||||||
|
$this->assertEquals( '𝔞', $result );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUnicode_bfr() {
|
||||||
|
$result = MMLParsingUtil::mapToFrakturUnicode( 'B' );
|
||||||
|
$this->assertEquals( '𝔅', $result );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUnicode_Cfr() {
|
||||||
|
$result = MMLParsingUtil::mapToFrakturUnicode( 'C' );
|
||||||
|
$this->assertEquals( 'ℭ', $result );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUnicodeUtf8Input() {
|
||||||
|
$result = MMLParsingUtil::mapToFrakturUnicode( '𝔄' );
|
||||||
|
$this->assertEquals( '𝔄', $result );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue