From 1a6f0b50cd0d97f142ae6813a48f105270bf8644 Mon Sep 17 00:00:00 2001 From: mundschenk_at Date: Sat, 15 Jun 2024 10:27:06 +0200 Subject: [PATCH 1/3] Add new pre- and post-processing groups --- src/fixes/class-registry.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/fixes/class-registry.php b/src/fixes/class-registry.php index 3178b05..7d330d1 100644 --- a/src/fixes/class-registry.php +++ b/src/fixes/class-registry.php @@ -43,13 +43,15 @@ */ class Registry { + const PRE_PROCESSING = 01; const CHARACTERS = 10; const SPACING_PRE_WORDS = 20; const PROCESS_WORDS = 30; const SPACING_POST_WORDS = 40; const HTML_INSERTION = 50; + const POST_PROCESSING = 99; - const GROUPS = [ self::CHARACTERS, self::SPACING_PRE_WORDS, self::PROCESS_WORDS, self::SPACING_POST_WORDS, self::HTML_INSERTION ]; + const GROUPS = [ self::PRE_PROCESSING, self::CHARACTERS, self::SPACING_PRE_WORDS, self::PROCESS_WORDS, self::SPACING_POST_WORDS, self::HTML_INSERTION, self::POST_PROCESSING ]; /** * An array of Node_Fix implementations indexed by groups. @@ -57,11 +59,13 @@ class Registry { * @var array */ private $node_fixes = [ + self::PRE_PROCESSING => [], self::CHARACTERS => [], self::SPACING_PRE_WORDS => [], self::PROCESS_WORDS => [], self::SPACING_POST_WORDS => [], self::HTML_INSERTION => [], + self::POST_PROCESSING => [], ]; /** From 99a7a7ed07721b35deaba5a0f169d2f7d41c3b93 Mon Sep 17 00:00:00 2001 From: mundschenk_at Date: Sat, 15 Jun 2024 10:28:54 +0200 Subject: [PATCH 2/3] Clean up return type declarations and docs --- src/fixes/class-default-registry.php | 8 ++++---- src/fixes/class-registry.php | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/fixes/class-default-registry.php b/src/fixes/class-default-registry.php index 0cd4953..2f1c4a3 100644 --- a/src/fixes/class-default-registry.php +++ b/src/fixes/class-default-registry.php @@ -104,7 +104,7 @@ function ( $index ) use ( $css_classes ) { /** * Also register the token fixes. * - * @var Token_Fix $fix A token fix class. + * @var class-string $fix A token fix class. */ foreach ( self::get_default_token_fixes() as $fix => $params ) { $arguments = []; @@ -128,7 +128,7 @@ function ( $index ) use ( $css_classes ) { * } * } */ - protected static function get_default_node_fixes() { + protected static function get_default_node_fixes(): array { return [ self::CHARACTERS => [ // Nodify anything that requires adjacent text awareness here. @@ -194,9 +194,9 @@ protected static function get_default_node_fixes() { /** * Returns a configuration array for the default token fixes. * - * @return array + * @return array,mixed[]> */ - protected static function get_default_token_fixes() { + protected static function get_default_token_fixes(): array { return [ Token_Fixes\Wrap_Hard_Hyphens_Fix::class => [], Token_Fixes\Smart_Dashes_Hyphen_Fix::class => [], diff --git a/src/fixes/class-registry.php b/src/fixes/class-registry.php index 7d330d1..56bb6f0 100644 --- a/src/fixes/class-registry.php +++ b/src/fixes/class-registry.php @@ -89,7 +89,7 @@ public function __construct() { * * @return Node_Fix[][] */ - public function get_node_fixes() { + public function get_node_fixes(): array { return $this->node_fixes; } From 6077f78848bb8a06079b768cc5c425384e4a02e6 Mon Sep 17 00:00:00 2001 From: mundschenk_at Date: Sat, 15 Jun 2024 10:30:58 +0200 Subject: [PATCH 3/3] Replace Settings::apply_character_mapping with Unicode_Remapping_Fix in post-processing --- src/class-php-typography.php | 2 +- src/class-settings.php | 38 ++---- src/fixes/class-default-registry.php | 4 + .../class-unicode-remapping-fix.php | 63 +++++++++ tests/class-php-typography-test.php | 1 + tests/class-settings-test.php | 36 ------ .../class-unicode-remapping-fix-test.php | 121 ++++++++++++++++++ 7 files changed, 199 insertions(+), 66 deletions(-) create mode 100644 src/fixes/node-fixes/class-unicode-remapping-fix.php create mode 100644 tests/fixes/node-fixes/class-unicode-remapping-fix-test.php diff --git a/src/class-php-typography.php b/src/class-php-typography.php index 7881ea4..15f7a17 100644 --- a/src/class-php-typography.php +++ b/src/class-php-typography.php @@ -227,7 +227,7 @@ private function process_textnodes_internal( \DOMDocument $dom, \DOMNode $body_n // Replace original node (if anything was changed). if ( $new !== $original ) { - $this->replace_node_with_html( $textnode, $settings->apply_character_mapping( $new ) ); + $this->replace_node_with_html( $textnode, $new ); } } } diff --git a/src/class-settings.php b/src/class-settings.php index 1d1dd42..7a873ba 100644 --- a/src/class-settings.php +++ b/src/class-settings.php @@ -52,6 +52,7 @@ * - `$unicode_mapping` * * Additional removed methods: + * - `apply_character_mapping` * - `array_map_assoc` (previously deprecated) * - custom_unit * - dash_style @@ -133,6 +134,9 @@ * @property-read bool $ignore_parser_errors Whether lenient parser error handling (output "best guess" HTML) is enabled. * @property-read ?callable $parser_errors_handler An optional handler for parser errors. The callable takes an array of error strings as its parameter. * + * Post-processing: + * @property-read array $unicode_character_mapping The Unicode character mapping (as some characters still have compatibility issues). + * * Setters for general attributes: * @method void set_classes_to_ignore( string[] $classes = ['vcard','noTypo'] ) Sets classes for which the typography of their children will be left untouched. * @method void set_ids_to_ignore( string[] $ids = [] ) Sets IDs for which the typography of their children will be left untouched. @@ -262,7 +266,7 @@ class Settings { const PARSER_ERRORS_IGNORE = 'parserErrorsIgnore'; const PARSER_ERRORS_HANDLER = 'parserErrorsHandler'; - // Unicode character remapping (some characters still have compatibility issues). + // Post-processing. const UNICODE_CHARACTER_MAPPING = 'unicodeCharacterMapping'; /** @@ -596,6 +600,10 @@ class Settings { 'default' => true, 'verify' => 'is_bool', ], + [ + 'property' => self::UNICODE_CHARACTER_MAPPING, + 'name' => 'unicode_character_mapping', + ], ]; /** @@ -759,34 +767,6 @@ public function remap_character( string $char, string $new_char ): void { } } - /** - * Remaps one or more strings. - * - * @since 6.5.0 - * - * @template T of string|string[] - * - * @param T $input The input string(s). - * - * @return T - */ - public function apply_character_mapping( $input ) { - - // Nothing for us to do. - if ( empty( $input ) || empty( $this->data[ self::UNICODE_CHARACTER_MAPPING ] ) ) { - return $input; - } - - $native_array = \is_array( $input ); - $data = (array) $input; - - foreach ( $data as $key => $string ) { - $data[ $key ] = \strtr( $string, $this->data[ self::UNICODE_CHARACTER_MAPPING ] ); - } - - return $native_array ? $data : $data[0]; // @phpstan-ignore-line -- Ignore generics/array clash - } - /** * (Re)set various options to their default values. */ diff --git a/src/fixes/class-default-registry.php b/src/fixes/class-default-registry.php index 2f1c4a3..752244b 100644 --- a/src/fixes/class-default-registry.php +++ b/src/fixes/class-default-registry.php @@ -188,6 +188,10 @@ protected static function get_default_node_fixes(): array { 'classes' => [ 'push-single', 'push-double', 'pull-single', 'pull-double' ], ], ], + + self::POST_PROCESSING => [ + Node_Fixes\Unicode_Remapping_Fix::class => [], + ], ]; } diff --git a/src/fixes/node-fixes/class-unicode-remapping-fix.php b/src/fixes/node-fixes/class-unicode-remapping-fix.php new file mode 100644 index 0000000..6bebbff --- /dev/null +++ b/src/fixes/node-fixes/class-unicode-remapping-fix.php @@ -0,0 +1,63 @@ + + * + * @since 7.0.0 + */ +class Unicode_Remapping_Fix extends Abstract_Node_Fix { + + /** + * Creates a new node fix. + */ + public function __construct() { + parent::__construct( true ); + } + + /** + * Apply the fix to a given textnode. + * + * @param \DOMText $textnode The DOM node. + * @param Settings $settings The settings to apply. + * @param bool $is_title Indicates if the processed tokens occur in a title/heading context. + * + * @return void + */ + public function apply( \DOMText $textnode, Settings $settings, $is_title ) { + if ( empty( $settings->unicode_character_mapping ) ) { + return; + } + + $textnode->data = \strtr( $textnode->data, $settings->unicode_character_mapping ); + } +} diff --git a/tests/class-php-typography-test.php b/tests/class-php-typography-test.php index 7ce9e89..c21d716 100644 --- a/tests/class-php-typography-test.php +++ b/tests/class-php-typography-test.php @@ -94,6 +94,7 @@ * @uses PHP_Typography\Fixes\Node_Fixes\Style_Ampersands_Fix * @uses PHP_Typography\Fixes\Node_Fixes\Style_Caps_Fix * @uses PHP_Typography\Fixes\Node_Fixes\Style_Numbers_Fix + * @uses PHP_Typography\Fixes\Node_Fixes\Unicode_Remapping_Fix * @uses PHP_Typography\Fixes\Node_Fixes\Unit_Spacing_Fix */ class PHP_Typography_Test extends Testcase { diff --git a/tests/class-settings-test.php b/tests/class-settings-test.php index a79b793..c262561 100644 --- a/tests/class-settings-test.php +++ b/tests/class-settings-test.php @@ -1508,40 +1508,4 @@ public function test_remap_character() { $this->assertCount( 2, $data[ Settings::UNICODE_CHARACTER_MAPPING ] ); $this->assertContains( 'x', $data[ Settings::UNICODE_CHARACTER_MAPPING ] ); } - - - /** - * Provides data for testing apply_character_mapping. - * - * @return array - */ - public function provide_apply_character_mapping_data() { - return [ - [ 'foobar', 'foobAz' ], - [ [ 'foobar' ], [ 'foobAz' ] ], - [ [ 'foobar', 'fugazi' ], [ 'foobAz', 'fugAzi' ] ], - [ '', '' ], - ]; - } - - /** - * Tests apply_character_mapping. - * - * @covers ::apply_character_mapping - * - * @dataProvider provide_apply_character_mapping_data - * - * @param string|string[] $input The input. - * @param string|string[] $result The expected result. - */ - public function test_apply_character_mapping( $input, $result ) { - $mapping = [ - 'a' => 'A', - 'r' => 'z', - ]; - - $s = new Settings( false, $mapping ); - - $this->assertSame( $result, $s->apply_character_mapping( $input ) ); - } } diff --git a/tests/fixes/node-fixes/class-unicode-remapping-fix-test.php b/tests/fixes/node-fixes/class-unicode-remapping-fix-test.php new file mode 100644 index 0000000..d810e77 --- /dev/null +++ b/tests/fixes/node-fixes/class-unicode-remapping-fix-test.php @@ -0,0 +1,121 @@ +fix = new Node_Fixes\Unicode_Remapping_Fix(); + } + + /** + * Provides data for testing apply. + * + * @return array + */ + public function provide_character_mapping_data() { + return [ + [ + 'foobar', + [ + 'a' => 'A', + 'r' => 'z', + ], + 'foobAz', + ], + [ + '', + [ + 'a' => 'A', + 'r' => 'z', + ], + '', + ], + ]; + } + + /** + * Test apply. + * + * @covers ::apply + * @covers ::__construct + * + * @uses PHP_Typography\Fixes\Node_Fixes\Simple_Regex_Replacement_Fix::apply + * + * @dataProvider provide_character_mapping_data + * + * @param string $input HTML input. + * @param string[] $mapping The character remapping to apply. + * @param string $result Expected result. + */ + public function test_apply( $input, array $mapping, $result ) { + $this->s = new Settings( false, $mapping ); + + $this->assertFixResultSame( $input, $result ); + } + + /** + * Test apply. + * + * @covers ::apply + * @covers ::__construct + * + * @uses PHP_Typography\Fixes\Node_Fixes\Simple_Regex_Replacement_Fix::apply + * + * @dataProvider provide_character_mapping_data + * + * @param string $input HTML input. + */ + public function test_apply_off( $input ) { + $this->s = new Settings( false, [] ); + + $this->assertFixResultSame( $input, $input ); + } +}