Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
UnicodePlural.php
Go to the documentation of this file.
1<?php
8
9use RuntimeException;
10
13 private const PRE = '{{PLURAL|';
14 private const POST = '}}';
15
22 public static function getPluralKeywords( $code ) {
23 $filePath = __DIR__ . '/../../data/plural-cldr.json';
24 $ruleData = json_decode( file_get_contents( $filePath ), true );
25
26 $ruleSet = $ruleData[ 'supplemental' ][ 'plurals-type-cardinal' ][ $code ] ?? null;
27 if ( $ruleSet === null ) {
28 return null;
29 }
30
31 $keywords = [];
32 foreach ( array_keys( $ruleSet ) as $name ) {
33 $keywords[] = str_replace( 'pluralRule-count-', '', $name );
34 }
35
36 return $keywords;
37 }
38
45 public static function hasPlural( $text ) {
46 return str_contains( $text, self::PRE );
47 }
48
56 public static function flattenMap( array $forms ) {
57 $list = [];
58 foreach ( $forms as $keyword => $value ) {
59 $list[] = [ $keyword, $value ];
60 }
61
62 return self::flattenList( $list );
63 }
64
72 public static function flattenList( array $formList ) {
73 $formatted = [];
74 foreach ( $formList as [ $keyword, $value ] ) {
75 $formatted[] = self::formatForm( $keyword, $value );
76 }
77
78 return self::PRE . implode( '|', $formatted ) . self::POST;
79 }
80
81 private static function formatForm( $keyword, $value ) {
82 $prefix = $keyword === 'other' ? '' : "$keyword=";
83 return $prefix . $value;
84 }
85
97 public static function unflatten( $text, $expectedKeywords ) {
98 [ $template, $instanceMap ] = self::parsePluralForms( $text );
99 return self::expandTemplate( $template, $instanceMap, $expectedKeywords );
100 }
101
108 public static function parsePluralForms( $text ) {
109 $m = [];
110 $pre = preg_quote( self::PRE, '/' );
111 $post = preg_quote( self::POST, '/' );
112
113 $ok = preg_match_all( "/$pre(.*)$post/Us", $text, $m );
114 if ( $ok === false ) {
115 throw new RuntimeException( "Plural regular expression failed for text: $text" );
116 }
117
118 $template = $text;
119 $instanceMap = [];
120
121 foreach ( $m[0] as $instanceIndex => $instanceText ) {
123
124 // Using preg_replace instead of str_replace because of the limit parameter
125 $pattern = '/' . preg_quote( $instanceText, '/' ) . '/';
126 $template = preg_replace( $pattern, $ph, $template, 1 );
127
128 $instanceForms = [];
129 foreach ( explode( '|', $m[ 1 ][ $instanceIndex ] ) as $form ) {
130 $m2 = [];
131 $ok = preg_match( "~\s*([a-z]+)\s*=(.+)~s", $form, $m2 );
132 $keyword = $ok ? $m2[ 1 ] : 'other';
133 $value = $ok ? trim( $m2[ 2 ] ) : $form;
134 $instanceForms[] = [ $keyword, $value ];
135 }
136
137 $instanceMap[$ph] = $instanceForms;
138 }
139
140 return [ $template, $instanceMap ];
141 }
142
151 public static function expandTemplate( $template, array $instanceMap, $expectedKeywords ) {
152 $formArray = [];
153
154 // Convert from list of forms to map of forms for easier processing
155 foreach ( $instanceMap as $ph => $list ) {
156 $instanceMap[ $ph ] = self::convertFormListToFormMap( $list, $expectedKeywords );
157 }
158
159 foreach ( $expectedKeywords as $keyword ) {
160 // Start with the whole string
161 $form = $template;
162
163 // Loop over each plural markup instance and replace it with the plural form belonging
164 // to the current index
165 foreach ( $instanceMap as $ph => $instanceFormMap ) {
166 // For missing forms, fall back to empty text.
167 $replacement = $instanceFormMap[ $keyword ] ?? '';
168 $form = str_replace( $ph, $replacement, $form );
169 }
170
171 $formArray[ $keyword ] = $form;
172 }
173
174 return $formArray;
175 }
176
177 public static function convertFormListToFormMap( array $formList, array $expectedKeywords ) {
178 $formMap = [];
179 foreach ( $formList as [ $keyword, $value ] ) {
180 $formMap[ $keyword ] = $value;
181 }
182
183 $sortedFormMap = [];
184 foreach ( $expectedKeywords as $keyword ) {
185 $sortedFormMap[ $keyword ] = $formMap[ $keyword ] ?? null;
186 }
187
188 return $sortedFormMap;
189 }
190}
static parsePluralForms( $text)
Parses plural markup into a structure form.
static expandTemplate( $template, array $instanceMap, $expectedKeywords)
Gives fully expanded forms given a template and parsed plural markup instances.
static unflatten( $text, $expectedKeywords)
Format translation with plural forms as array of forms.
static flattenList(array $formList)
Format plural forms list as single string.
static getPluralKeywords( $code)
Returns CLDR plural rule for given language.
static hasPlural( $text)
Quick way to check if the text contains plural syntax.
static flattenMap(array $forms)
Format plural forms map as single string suitable for translation.
Essentially random collection of helper functions, similar to GlobalFunctions.php.
Definition Utilities.php:31
static getPlaceholder()
Returns a random string that can be used as placeholder in strings.