7 if( defined( 'MEDIAWIKI' ) ) {
10 # In general you should not make customizations in these language files
11 # directly, but should use the MediaWiki: special namespace to customize
12 # user interface messages through the wiki.
13 # See http://meta.wikipedia.org/wiki/MediaWiki_namespace
15 # NOTE TO TRANSLATORS: Do not copy this whole file when making translations!
16 # A lot of common constants and a base class with inheritable methods are
17 # defined here, which should not be redefined. See the other LanguageXx.php
21 #--------------------------------------------------------------------------
22 # Language-specific text
23 #--------------------------------------------------------------------------
25 if($wgMetaNamespace === FALSE)
26 $wgMetaNamespace = str_replace( ' ', '_', $wgSitename );
28 /* private */ $wgNamespaceNamesEn = array(
30 NS_SPECIAL
=> 'Special',
34 NS_USER_TALK
=> 'User_talk',
35 NS_PROJECT
=> $wgMetaNamespace,
36 NS_PROJECT_TALK
=> $wgMetaNamespace . '_talk',
38 NS_IMAGE_TALK
=> 'Image_talk',
39 NS_MEDIAWIKI
=> 'MediaWiki',
40 NS_MEDIAWIKI_TALK
=> 'MediaWiki_talk',
41 NS_TEMPLATE
=> 'Template',
42 NS_TEMPLATE_TALK
=> 'Template_talk',
44 NS_HELP_TALK
=> 'Help_talk',
45 NS_CATEGORY
=> 'Category',
46 NS_CATEGORY_TALK
=> 'Category_talk',
49 if(isset($wgExtraNamespaces)) {
50 $wgNamespaceNamesEn=$wgNamespaceNamesEn+
$wgExtraNamespaces;
53 /* private */ $wgDefaultUserOptionsEn = array(
61 'skin' => $wgDefaultSkin,
66 'highlightbroken' => 1,
70 'editsectiononrightclick'=> 0,
76 'rememberpassword' => 0,
77 'enotifwatchlistpages' => 0,
78 'enotifusertalkpages' => 1,
79 'enotifminoredits' => 0,
80 'enotifrevealaddr' => 0,
81 'shownumberswatching' => 1,
83 'externaleditor' => 0,
86 'numberheadings' => 0,
87 'uselivepreview' => 0,
88 'watchlistdays' => 3.0,
91 /* private */ $wgQuickbarSettingsEn = array(
92 'None', 'Fixed left', 'Fixed right', 'Floating left', 'Floating right'
95 /* private */ $wgSkinNamesEn = array(
96 'standard' => 'Classic',
97 'nostalgia' => 'Nostalgia',
98 'cologneblue' => 'Cologne Blue',
99 'davinci' => 'DaVinci',
101 'monobook' => 'MonoBook',
102 'myskin' => 'MySkin',
106 /* private */ $wgMathNamesEn = array(
107 MW_MATH_PNG
=> 'mw_math_png',
108 MW_MATH_SIMPLE
=> 'mw_math_simple',
109 MW_MATH_HTML
=> 'mw_math_html',
110 MW_MATH_SOURCE
=> 'mw_math_source',
111 MW_MATH_MODERN
=> 'mw_math_modern',
112 MW_MATH_MATHML
=> 'mw_math_mathml'
116 * Whether to use user or default setting in Language::date()
118 * NOTE: the array string values are no longer important!
119 * The actual date format functions are now called for the selection in
120 * Special:Preferences, and the 'datedefault' message for MW_DATE_DEFAULT.
122 * The array keys make up the set of formats which this language allows
123 * the user to select. It's exposed via Language::getDateFormats().
127 $wgDateFormatsEn = array(
128 MW_DATE_DEFAULT
=> 'No preference',
129 MW_DATE_DMY
=> '16:12, 15 January 2001',
130 MW_DATE_MDY
=> '16:12, January 15, 2001',
131 MW_DATE_YMD
=> '16:12, 2001 January 15',
132 MW_DATE_ISO
=> '2001-01-15 16:12:34'
135 /* private */ $wgUserTogglesEn = array(
145 'editsectiononrightclick',
155 'enotifwatchlistpages',
156 'enotifusertalkpages',
159 'shownumberswatching',
171 /* private */ $wgBookstoreListEn = array(
172 'AddALL' => 'http://www.addall.com/New/Partner.cgi?query=$1&type=ISBN',
173 'PriceSCAN' => 'http://www.pricescan.com/books/bookDetail.asp?isbn=$1',
174 'Barnes & Noble' => 'http://search.barnesandnoble.com/bookSearch/isbnInquiry.asp?isbn=$1',
175 'Amazon.com' => 'http://www.amazon.com/exec/obidos/ISBN=$1'
178 # Read language names
179 global $wgLanguageNames;
181 require_once( 'Names.php' );
183 $wgLanguageNamesEn =& $wgLanguageNames;
186 /* private */ $wgWeekdayNamesEn = array(
187 'sunday', 'monday', 'tuesday', 'wednesday', 'thursday',
192 /* private */ $wgMonthNamesEn = array(
193 'january', 'february', 'march', 'april', 'may_long', 'june',
194 'july', 'august', 'september', 'october', 'november',
197 /* private */ $wgMonthNamesGenEn = array(
198 'january-gen', 'february-gen', 'march-gen', 'april-gen', 'may-gen', 'june-gen',
199 'july-gen', 'august-gen', 'september-gen', 'october-gen', 'november-gen',
203 /* private */ $wgMonthAbbreviationsEn = array(
204 'jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug',
205 'sep', 'oct', 'nov', 'dec'
208 # Note to translators:
209 # Please include the English words as synonyms. This allows people
210 # from other wikis to contribute more easily.
212 /* private */ $wgMagicWordsEn = array(
214 'redirect' => array( 0, '#REDIRECT' ),
215 'notoc' => array( 0, '__NOTOC__' ),
216 'nogallery' => array( 0, '__NOGALLERY__' ),
217 'forcetoc' => array( 0, '__FORCETOC__' ),
218 'toc' => array( 0, '__TOC__' ),
219 'noeditsection' => array( 0, '__NOEDITSECTION__' ),
220 'start' => array( 0, '__START__' ),
221 'currentmonth' => array( 1, 'CURRENTMONTH' ),
222 'currentmonthname' => array( 1, 'CURRENTMONTHNAME' ),
223 'currentmonthnamegen' => array( 1, 'CURRENTMONTHNAMEGEN' ),
224 'currentmonthabbrev' => array( 1, 'CURRENTMONTHABBREV' ),
225 'currentday' => array( 1, 'CURRENTDAY' ),
226 'currentday2' => array( 1, 'CURRENTDAY2' ),
227 'currentdayname' => array( 1, 'CURRENTDAYNAME' ),
228 'currentyear' => array( 1, 'CURRENTYEAR' ),
229 'currenttime' => array( 1, 'CURRENTTIME' ),
230 'numberofpages' => array( 1, 'NUMBEROFPAGES' ),
231 'numberofarticles' => array( 1, 'NUMBEROFARTICLES' ),
232 'numberoffiles' => array( 1, 'NUMBEROFFILES' ),
233 'numberofusers' => array( 1, 'NUMBEROFUSERS' ),
234 'pagename' => array( 1, 'PAGENAME' ),
235 'pagenamee' => array( 1, 'PAGENAMEE' ),
236 'namespace' => array( 1, 'NAMESPACE' ),
237 'namespacee' => array( 1, 'NAMESPACEE' ),
238 'talkspace' => array( 1, 'TALKSPACE' ),
239 'talkspacee' => array( 1, 'TALKSPACEE' ),
240 'subjectspace' => array( 1, 'SUBJECTSPACE', 'ARTICLESPACE' ),
241 'subjectspacee' => array( 1, 'SUBJECTSPACEE', 'ARTICLESPACEE' ),
242 'fullpagename' => array( 1, 'FULLPAGENAME' ),
243 'fullpagenamee' => array( 1, 'FULLPAGENAMEE' ),
244 'subpagename' => array( 1, 'SUBPAGENAME' ),
245 'subpagenamee' => array( 1, 'SUBPAGENAMEE' ),
246 'basepagename' => array( 1, 'BASEPAGENAME' ),
247 'basepagenamee' => array( 1, 'BASEPAGENAMEE' ),
248 'talkpagename' => array( 1, 'TALKPAGENAME' ),
249 'talkpagenamee' => array( 1, 'TALKPAGENAMEE' ),
250 'subjectpagename' => array( 1, 'SUBJECTPAGENAME', 'ARTICLEPAGENAME' ),
251 'subjectpagenamee' => array( 1, 'SUBJECTPAGENAMEE', 'ARTICLEPAGENAMEE' ),
252 'msg' => array( 0, 'MSG:' ),
253 'subst' => array( 0, 'SUBST:' ),
254 'msgnw' => array( 0, 'MSGNW:' ),
255 'end' => array( 0, '__END__' ),
256 'img_thumbnail' => array( 1, 'thumbnail', 'thumb' ),
257 'img_manualthumb' => array( 1, 'thumbnail=$1', 'thumb=$1'),
258 'img_right' => array( 1, 'right' ),
259 'img_left' => array( 1, 'left' ),
260 'img_none' => array( 1, 'none' ),
261 'img_width' => array( 1, '$1px' ),
262 'img_center' => array( 1, 'center', 'centre' ),
263 'img_framed' => array( 1, 'framed', 'enframed', 'frame' ),
264 'int' => array( 0, 'INT:' ),
265 'sitename' => array( 1, 'SITENAME' ),
266 'ns' => array( 0, 'NS:' ),
267 'localurl' => array( 0, 'LOCALURL:' ),
268 'localurle' => array( 0, 'LOCALURLE:' ),
269 'server' => array( 0, 'SERVER' ),
270 'servername' => array( 0, 'SERVERNAME' ),
271 'scriptpath' => array( 0, 'SCRIPTPATH' ),
272 'grammar' => array( 0, 'GRAMMAR:' ),
273 'notitleconvert' => array( 0, '__NOTITLECONVERT__', '__NOTC__'),
274 'nocontentconvert' => array( 0, '__NOCONTENTCONVERT__', '__NOCC__'),
275 'currentweek' => array( 1, 'CURRENTWEEK' ),
276 'currentdow' => array( 1, 'CURRENTDOW' ),
277 'revisionid' => array( 1, 'REVISIONID' ),
278 'plural' => array( 0, 'PLURAL:' ),
279 'fullurl' => array( 0, 'FULLURL:' ),
280 'fullurle' => array( 0, 'FULLURLE:' ),
281 'lcfirst' => array( 0, 'LCFIRST:' ),
282 'ucfirst' => array( 0, 'UCFIRST:' ),
283 'lc' => array( 0, 'LC:' ),
284 'uc' => array( 0, 'UC:' ),
285 'raw' => array( 0, 'RAW:' ),
286 'displaytitle' => array( 1, 'DISPLAYTITLE' ),
287 'rawsuffix' => array( 1, 'R' ),
288 'newsectionlink' => array( 1, '__NEWSECTIONLINK__' ),
289 'currentversion' => array( 1, 'CURRENTVERSION' ),
290 'urlencode' => array( 0, 'URLENCODE:' ),
291 'currenttimestamp' => array( 1, 'CURRENTTIMESTAMP' ),
292 'directionmark' => array( 1, 'DIRECTIONMARK', 'DIRMARK' ),
293 'language' => array( 0, '#LANGUAGE:' ),
294 'contentlanguage' => array( 1, 'CONTENTLANGUAGE', 'CONTENTLANG' ),
295 'pagesinnamespace' => array( 1, 'PAGESINNAMESPACE:', 'PAGESINNS:' ),
296 'numberofadmins' => array( 1, 'NUMBEROFADMINS' ),
297 'formatnum' => array( 0, 'FORMATNUM' ),
301 if (!$wgCachedMessageArrays) {
302 require_once('Messages.php');
305 /* a fake language converter */
306 class fakeConverter
{
308 function fakeConverter($langobj) {$this->mLang
= $langobj;}
309 function convert($t, $i) {return $t;}
310 function parserConvert($t, $p) {return $t;}
311 function getVariants() { return array( $this->mLang
->getCode() ); }
312 function getPreferredVariant() {return $this->mLang
->getCode(); }
313 function findVariantLink(&$l, &$n) {}
314 function getExtraHashOptions() {return '';}
315 function getParsedTitle() {return '';}
316 function markNoConversion($text) {return $text;}
317 function convertCategoryKey( $key ) {return $key; }
318 function convertLinkToAllVariants($text){ return array( $this->mLang
->getCode() => $text); }
322 #--------------------------------------------------------------------------
323 # Internationalisation code
324 #--------------------------------------------------------------------------
328 function __construct() {
329 $this->mConverter
= new fakeConverter($this);
333 * Exports the default user options as defined in
334 * $wgDefaultUserOptionsEn, user preferences can override some of these
335 * depending on what's in (Local|Default)Settings.php and some defines.
339 function getDefaultUserOptions() {
340 global $wgDefaultUserOptionsEn;
341 return $wgDefaultUserOptionsEn;
345 * Exports $wgBookstoreListEn
348 function getBookstoreList() {
349 global $wgBookstoreListEn;
350 return $wgBookstoreListEn;
356 function getNamespaces() {
357 global $wgNamespaceNamesEn;
358 return $wgNamespaceNamesEn;
362 * A convenience function that returns the same thing as
363 * getNamespaces() except with the array values changed to ' '
364 * where it found '_', useful for producing output to be displayed
365 * e.g. in <select> forms.
369 function getFormattedNamespaces() {
370 $ns = $this->getNamespaces();
371 foreach($ns as $k => $v) {
372 $ns[$k] = strtr($v, '_', ' ');
378 * Get a namespace value by key
380 * $mw_ns = $wgContLang->getNsText( NS_MEDIAWIKI );
381 * echo $mw_ns; // prints 'MediaWiki'
384 * @param int $index the array key of the namespace to return
385 * @return mixed, string if the namespace value exists, otherwise false
387 function getNsText( $index ) {
388 $ns = $this->getNamespaces();
389 return isset( $ns[$index] ) ?
$ns[$index] : false;
393 * A convenience function that returns the same thing as
394 * getNsText() except with '_' changed to ' ', useful for
399 function getFormattedNsText( $index ) {
400 $ns = $this->getNsText( $index );
401 return strtr($ns, '_', ' ');
405 * Get a namespace key by value, case insensetive.
407 * @param string $text
408 * @return mixed An integer if $text is a valid value otherwise false
410 function getNsIndex( $text ) {
411 $ns = $this->getNamespaces();
413 foreach ( $ns as $i => $n ) {
414 if ( strcasecmp( $n, $text ) == 0)
421 * short names for language variants used for language conversion links.
423 * @param string $code
426 function getVariantname( $code ) {
427 return wfMsg( "variantname-$code" );
430 function specialPage( $name ) {
431 return $this->getNsText(NS_SPECIAL
) . ':' . $name;
434 function getQuickbarSettings() {
435 global $wgQuickbarSettingsEn;
436 return $wgQuickbarSettingsEn;
439 function getSkinNames() {
440 global $wgSkinNamesEn;
441 return $wgSkinNamesEn;
444 function getMathNames() {
445 global $wgMathNamesEn;
446 return $wgMathNamesEn;
449 function getDateFormats() {
450 global $wgDateFormatsEn;
451 return $wgDateFormatsEn;
454 function getUserToggles() {
455 global $wgUserTogglesEn;
456 return $wgUserTogglesEn;
459 function getUserToggle( $tog ) {
460 return wfMsg( "tog-$tog" );
463 function getLanguageNames() {
464 global $wgLanguageNamesEn;
465 return $wgLanguageNamesEn;
468 function getLanguageName( $code ) {
469 global $wgLanguageNamesEn;
470 if ( ! array_key_exists( $code, $wgLanguageNamesEn ) ) {
473 return $wgLanguageNamesEn[$code];
476 function getMonthName( $key ) {
477 global $wgMonthNamesEn, $wgContLang;
478 // see who called us and use the correct message function
479 if( get_class( $wgContLang->getLangObj() ) == get_class( $this ) )
480 return wfMsgForContent($wgMonthNamesEn[$key-1]);
482 return wfMsg($wgMonthNamesEn[$key-1]);
485 /* by default we just return base form */
486 function getMonthNameGen( $key ) {
487 return $this->getMonthName( $key );
490 function getMonthAbbreviation( $key ) {
491 global $wgMonthAbbreviationsEn, $wgContLang;
492 // see who called us and use the correct message function
493 if( get_class( $wgContLang->getLangObj() ) == get_class( $this ) )
494 return wfMsgForContent(@$wgMonthAbbreviationsEn[$key-1]);
496 return wfMsg(@$wgMonthAbbreviationsEn[$key-1]);
499 function getWeekdayName( $key ) {
500 global $wgWeekdayNamesEn, $wgContLang;
501 // see who called us and use the correct message function
502 if( get_class( $wgContLang->getLangObj() ) == get_class( $this ) )
503 return wfMsgForContent($wgWeekdayNamesEn[$key-1]);
505 return wfMsg($wgWeekdayNamesEn[$key-1]);
509 * Used by date() and time() to adjust the time output.
511 * @param int $ts the time in date('YmdHis') format
512 * @param mixed $tz adjust the time by this amount (default false,
513 * mean we get user timecorrection setting)
517 function userAdjust( $ts, $tz = false ) {
518 global $wgUser, $wgLocalTZoffset;
521 $tz = $wgUser->getOption( 'timecorrection' );
524 #Â minutes and hours differences:
529 #Â Global offset in minutes.
530 if( isset($wgLocalTZoffset) ) {
531 $hrDiff = $wgLocalTZoffset %
60;
532 $minDiff = $wgLocalTZoffset - ($hrDiff * 60);
534 } elseif ( strpos( $tz, ':' ) !== false ) {
535 $tzArray = explode( ':', $tz );
536 $hrDiff = intval($tzArray[0]);
537 $minDiff = intval($hrDiff < 0 ?
-$tzArray[1] : $tzArray[1]);
539 $hrDiff = intval( $tz );
542 # No difference ? Return time unchanged
543 if ( 0 == $hrDiff && 0 == $minDiff ) { return $ts; }
545 #Â Generate an adjusted date
547 (int)substr( $ts, 8, 2) ) +
$hrDiff, # Hours
548 (int)substr( $ts, 10, 2 ) +
$minDiff, # Minutes
549 (int)substr( $ts, 12, 2 ), # Seconds
550 (int)substr( $ts, 4, 2 ), # Month
551 (int)substr( $ts, 6, 2 ), # Day
552 (int)substr( $ts, 0, 4 ) ); #Year
553 return date( 'YmdHis', $t );
557 * This is meant to be used by time(), date(), and timeanddate() to get
558 * the date preference they're supposed to use, it should be used in
562 * function timeanddate([...], $format = true) {
563 * $datePreference = $this->dateFormat($format);
567 * @param mixed $usePrefs: if true, the user's preference is used
568 * if false, the site/language default is used
569 * if int/string, assumed to be a format.
572 function dateFormat( $usePrefs = true ) {
575 if( is_bool( $usePrefs ) ) {
577 $datePreference = $wgUser->getOption( 'date' );
579 $options = $this->getDefaultUserOptions();
580 $datePreference = (string)$options['date'];
583 $datePreference = (string)$usePrefs;
587 if( $datePreference == '' ) {
588 return MW_DATE_DEFAULT
;
591 return $datePreference;
596 * @param mixed $ts the time format which needs to be turned into a
597 * date('YmdHis') format with wfTimestamp(TS_MW,$ts)
598 * @param bool $adj whether to adjust the time output according to the
599 * user configured offset ($timecorrection)
600 * @param mixed $format true to use user's date format preference
601 * @param string $timecorrection the time offset as returned by
602 * validateTimeZone() in Special:Preferences
605 function date( $ts, $adj = false, $format = true, $timecorrection = false ) {
606 global $wgUser, $wgAmericanDates;
608 if ( $adj ) { $ts = $this->userAdjust( $ts, $timecorrection ); }
610 $datePreference = $this->dateFormat( $format );
611 if( $datePreference == MW_DATE_DEFAULT
) {
612 $datePreference = $wgAmericanDates ? MW_DATE_MDY
: MW_DATE_DMY
;
615 $month = $this->formatMonth( substr( $ts, 4, 2 ), $datePreference );
616 $day = $this->formatDay( substr( $ts, 6, 2 ), $datePreference );
617 $year = $this->formatNum( substr( $ts, 0, 4 ), true );
619 switch( $datePreference ) {
620 case MW_DATE_DMY
: return "$day $month $year";
621 case MW_DATE_YMD
: return "$year $month $day";
622 case MW_DATE_ISO
: return substr($ts, 0, 4). '-' . substr($ts, 4, 2). '-' .substr($ts, 6, 2);
623 default: return "$month $day, $year";
629 * @param mixed $ts the time format which needs to be turned into a
630 * date('YmdHis') format with wfTimestamp(TS_MW,$ts)
631 * @param bool $adj whether to adjust the time output according to the
632 * user configured offset ($timecorrection)
633 * @param mixed $format true to use user's date format preference
634 * @param string $timecorrection the time offset as returned by
635 * validateTimeZone() in Special:Preferences
638 function time( $ts, $adj = false, $format = true, $timecorrection = false ) {
641 if ( $adj ) { $ts = $this->userAdjust( $ts, $timecorrection ); }
642 $datePreference = $this->dateFormat( $format );
644 $sep = $this->timeSeparator( $format );
646 $hh = substr( $ts, 8, 2 );
647 $mm = substr( $ts, 10, 2 );
648 $ss = substr( $ts, 12, 2 );
650 if ( $datePreference != MW_DATE_ISO
) {
651 $hh = $this->formatNum( $hh, true );
652 $mm = $this->formatNum( $mm, true );
653 //$ss = $this->formatNum( $ss, true );
654 return $hh . $sep . $mm;
656 return $hh . ':' . $mm . ':' . $ss;
661 * Default separator character between hours, minutes, and seconds.
662 * Will be used by Language::time() for non-ISO formats.
663 * (ISO will always use a colon.)
666 function timeSeparator( $format ) {
671 * String to insert between the time and the date in a combined
672 * string. Should include any relevant whitespace.
675 function timeDateSeparator( $format ) {
680 * Return true if the time should display before the date.
684 function timeBeforeDate() {
688 function formatMonth( $month, $format ) {
689 return $this->getMonthName( $month );
692 function formatDay( $day, $format ) {
693 return $this->formatNum( 0 +
$day, true );
698 * @param mixed $ts the time format which needs to be turned into a
699 * date('YmdHis') format with wfTimestamp(TS_MW,$ts)
700 * @param bool $adj whether to adjust the time output according to the
701 * user configured offset ($timecorrection)
703 * @param mixed $format what format to return, if it's false output the
704 * default one (default true)
705 * @param string $timecorrection the time offset as returned by
706 * validateTimeZone() in Special:Preferences
709 function timeanddate( $ts, $adj = false, $format = true, $timecorrection = false) {
712 $datePreference = $this->dateFormat($format);
713 switch ( $datePreference ) {
714 case MW_DATE_ISO
: return $this->date( $ts, $adj, $format, $timecorrection ) . ' ' .
715 $this->time( $ts, $adj, $format, $timecorrection );
717 $time = $this->time( $ts, $adj, $format, $timecorrection );
718 $sep = $this->timeDateSeparator( $datePreference );
719 $date = $this->date( $ts, $adj, $format, $timecorrection );
720 return $this->timeBeforeDate( $datePreference )
721 ?
$time . $sep . $date
722 : $date . $sep . $time;
726 function getMessage( $key ) {
727 global $wgAllMessagesEn;
728 return @$wgAllMessagesEn[$key];
731 function getAllMessages() {
732 global $wgAllMessagesEn;
733 return $wgAllMessagesEn;
736 function iconv( $in, $out, $string ) {
737 # For most languages, this is a wrapper for iconv
738 return iconv( $in, $out, $string );
741 function ucfirst( $string ) {
742 # For most languages, this is a wrapper for ucfirst()
743 return ucfirst( $string );
746 function uc( $str ) {
747 return strtoupper( $str );
750 function lcfirst( $s ) {
751 return strtolower( $s{0} ). substr( $s, 1 );
754 function lc( $str ) {
755 return strtolower( $str );
758 function ucwords($str) {
759 return ucwords( strtolower( $str ) );
762 # capitalize words at word breaks
763 function ucwordbreaks($str){
764 return preg_replace_callback(
765 '/\b([\w\x80-\xff]+)\b/',
766 create_function( '$matches', '
768 return $wgContLang->ucfirst($matches[1]);
773 function checkTitleEncoding( $s ) {
774 global $wgInputEncoding;
776 # Check for UTF-8 URLs; Internet Explorer produces these if you
777 # type non-ASCII chars in the URL bar or follow unescaped links.
778 $ishigh = preg_match( '/[\x80-\xff]/', $s);
779 $isutf = ($ishigh ?
preg_match( '/^([\x00-\x7f]|[\xc0-\xdf][\x80-\xbf]|' .
780 '[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xf7][\x80-\xbf]{3})+$/', $s ) : true );
782 if( ($wgInputEncoding != 'utf-8') and $ishigh and $isutf )
783 return @iconv
( 'UTF-8', $wgInputEncoding, $s );
785 if( ($wgInputEncoding == 'utf-8') and $ishigh and !$isutf )
786 return utf8_encode( $s );
788 # Other languages can safely leave this function, or replace
789 # it with one to detect and convert another legacy encoding.
794 * Some languages have special punctuation to strip out
795 * or characters which need to be converted for MySQL's
796 * indexing to grok it correctly. Make such changes here.
801 function stripForSearch( $in ) {
802 return strtolower( $in );
805 function convertForSearchResult( $termsArray ) {
806 # some languages, e.g. Chinese, need to do a conversion
807 # in order for search results to be displayed correctly
812 * Get the first character of a string. In ASCII, return
813 * first byte of the string. UTF8 and others have to
819 function firstChar( $s ) {
823 function initEncoding() {
824 # Some languages may have an alternate char encoding option
825 # (Esperanto X-coding, Japanese furigana conversion, etc)
826 # If this language is used as the primary content language,
827 # an override to the defaults can be set here on startup.
828 #global $wgInputEncoding, $wgOutputEncoding, $wgEditEncoding;
831 function setAltEncoding() {
832 # Some languages may have an alternate char encoding option
833 # (Esperanto X-coding, Japanese furigana conversion, etc)
834 # If 'altencoding' is checked in user prefs, this gives a
835 # chance to swap out the default encoding settings.
836 #global $wgInputEncoding, $wgOutputEncoding, $wgEditEncoding;
839 function recodeForEdit( $s ) {
840 # For some languages we'll want to explicitly specify
841 # which characters make it into the edit box raw
842 # or are converted in some way or another.
843 # Note that if wgOutputEncoding is different from
844 # wgInputEncoding, this text will be further converted
845 # to wgOutputEncoding.
846 global $wgInputEncoding, $wgEditEncoding;
847 if( $wgEditEncoding == '' or
848 $wgEditEncoding == $wgInputEncoding ) {
851 return $this->iconv( $wgInputEncoding, $wgEditEncoding, $s );
855 function recodeInput( $s ) {
856 # Take the previous into account.
857 global $wgInputEncoding, $wgOutputEncoding, $wgEditEncoding;
858 if($wgEditEncoding != "") {
859 $enc = $wgEditEncoding;
861 $enc = $wgOutputEncoding;
863 if( $enc == $wgInputEncoding ) {
866 return $this->iconv( $enc, $wgInputEncoding, $s );
871 * For right-to-left language support
875 function isRTL() { return false; }
878 * A hidden direction mark (LRM or RLM), depending on the language direction
882 function getDirMark() { return $this->isRTL() ?
"\xE2\x80\x8F" : "\xE2\x80\x8E"; }
885 * To allow "foo[[bar]]" to extend the link over the whole word "foobar"
889 function linkPrefixExtension() { return false; }
891 function &getMagicWords() {
892 global $wgMagicWordsEn;
893 return $wgMagicWordsEn;
896 # Fill a MagicWord object with data from here
897 function getMagic( &$mw ) {
898 if ( !isset( $this->mMagicExtensions
) ) {
899 $this->mMagicExtensions
= array();
900 wfRunHooks( 'LanguageGetMagic', array( &$this->mMagicExtensions
, $this->getCode() ) );
902 if ( isset( $this->mMagicExtensions
[$mw->mId
] ) ) {
903 $rawEntry = $this->mMagicExtensions
[$mw->mId
];
905 $magicWords =& $this->getMagicWords();
906 if ( isset( $magicWords[$mw->mId
] ) ) {
907 $rawEntry = $magicWords[$mw->mId
];
909 # Fall back to English if local list is incomplete
910 $magicWords =& Language
::getMagicWords();
911 $rawEntry = $magicWords[$mw->mId
];
915 $mw->mCaseSensitive
= $rawEntry[0];
916 $mw->mSynonyms
= array_slice( $rawEntry, 1 );
920 * Italic is unsuitable for some languages
924 * @param string $text The text to be emphasized.
927 function emphasize( $text ) {
928 return "<em>$text</em>";
932 * Normally we output all numbers in plain en_US style, that is
933 * 293,291.235 for twohundredninetythreethousand-twohundredninetyone
934 * point twohundredthirtyfive. However this is not sutable for all
935 * languages, some such as Pakaran want ੨੯੩,੨੯੫.੨੩੫ and others such as
936 * Icelandic just want to use commas instead of dots, and dots instead
937 * of commas like "293.291,235".
939 * An example of this function being called:
941 * wfMsg( 'message', $wgLang->formatNum( $num ) )
944 * See LanguageGu.php for the Gujarati implementation and
945 * LanguageIs.php for the , => . and . => , implementation.
947 * @todo check if it's viable to use localeconv() for the decimal
950 * @param mixed $number the string to be formatted, should be an integer or
951 * a floating point number.
952 * @param bool $nocommafy Set to true for special numbers like dates
955 function formatNum( $number, $nocommafy = false ) {
956 global $wgTranslateNumerals;
958 $number = $this->commafy($number);
959 $s = $this->separatorTransformTable();
960 if (!is_null($s)) { $number = strtr($number, $s); }
963 if ($wgTranslateNumerals) {
964 $s = $this->digitTransformTable();
965 if (!is_null($s)) { $number = strtr($number, $s); }
972 * Adds commas to a given number
977 function commafy($_) {
978 return strrev((string)preg_replace('/(\d{3})(?=\d)(?!\d*\.)/','$1,',strrev($_)));
981 function digitTransformTable() {
985 function separatorTransformTable() {
991 * For the credit list in includes/Credits.php (action=credits)
996 function listToText( $l ) {
999 for ($i = $m; $i >= 0; $i--) {
1002 } else if ($i == $m - 1) {
1003 $s = $l[$i] . ' ' . wfMsg('and') . ' ' . $s;
1005 $s = $l[$i] . ', ' . $s;
1011 # Crop a string from the beginning or end to a certain number of bytes.
1012 # (Bytes are used because our storage has limited byte lengths for some
1013 # columns in the database.) Multibyte charsets will need to make sure that
1014 # only whole characters are included!
1016 # $length does not include the optional ellipsis.
1017 # If $length is negative, snip from the beginning
1018 function truncate( $string, $length, $ellipsis = '' ) {
1019 if( $length == 0 ) {
1022 if ( strlen( $string ) <= abs( $length ) ) {
1026 $string = substr( $string, 0, $length );
1027 return $string . $ellipsis;
1029 $string = substr( $string, $length );
1030 return $ellipsis . $string;
1035 * Grammatical transformations, needed for inflected languages
1036 * Invoked by putting {{grammar:case|word}} in a message
1038 * @param string $word
1039 * @param string $case
1042 function convertGrammar( $word, $case ) {
1043 global $wgGrammarForms;
1044 if ( isset($wgGrammarForms['en'][$case][$word]) ) {
1045 return $wgGrammarForms['en'][$case][$word];
1051 * Plural form transformations, needed for some languages.
1052 * For example, where are 3 form of plural in Russian and Polish,
1053 * depending on "count mod 10". See [[w:Plural]]
1054 * For English it is pretty simple.
1056 * Invoked by putting {{plural:count|wordform1|wordform2}}
1057 * or {{plural:count|wordform1|wordform2|wordform3}}
1059 * Example: {{plural:{{NUMBEROFARTICLES}}|article|articles}}
1061 * @param integer $count
1062 * @param string $wordform1
1063 * @param string $wordform2
1064 * @param string $wordform3 (optional)
1067 function convertPlural( $count, $w1, $w2, $w3) {
1068 return $count == '1' ?
$w1 : $w2;
1072 * For translaing of expiry times
1073 * @param string The validated block time in English
1074 * @return Somehow translated block time
1075 * @see LanguageFi.php for example implementation
1077 function translateBlockExpiry( $str ) {
1079 $scBlockExpiryOptions = wfMsg( 'ipboptions' );
1081 if ( $scBlockExpiryOptions == '-') {
1085 foreach (explode(',', $scBlockExpiryOptions) as $option) {
1086 if ( strpos($option, ":") === false )
1088 list($show, $value) = explode(":", $option);
1089 if ( strcmp ( $str, $value) == 0 )
1090 return '<span title="' . htmlspecialchars($str). '">' .
1091 htmlspecialchars( trim( $show ) ) . '</span>';
1098 * languages like Chinese need to be segmented in order for the diff
1101 * @param string $text
1104 function segmentForDiff( $text ) {
1109 * and unsegment to show the result
1111 * @param string $text
1114 function unsegmentForDiff( $text ) {
1118 # convert text to different variants of a language.
1119 function convert( $text, $isTitle = false) {
1120 return $this->mConverter
->convert($text, $isTitle);
1123 # Convert text from within Parser
1124 function parserConvert( $text, &$parser ) {
1125 return $this->mConverter
->parserConvert( $text, $parser );
1129 * Perform output conversion on a string, and encode for safe HTML output.
1130 * @param string $text
1131 * @param bool $isTitle -- wtf?
1133 * @todo this should get integrated somewhere sane
1135 function convertHtml( $text, $isTitle = false ) {
1136 return htmlspecialchars( $this->convert( $text, $isTitle ) );
1139 function convertCategoryKey( $key ) {
1140 return $this->mConverter
->convertCategoryKey( $key );
1144 * get the list of variants supported by this langauge
1145 * see sample implementation in LanguageZh.php
1147 * @return array an array of language codes
1149 function getVariants() {
1150 return $this->mConverter
->getVariants();
1154 function getPreferredVariant() {
1155 return $this->mConverter
->getPreferredVariant();
1159 * if a language supports multiple variants, it is
1160 * possible that non-existing link in one variant
1161 * actually exists in another variant. this function
1162 * tries to find it. See e.g. LanguageZh.php
1164 * @param string $link the name of the link
1165 * @param mixed $nt the title object of the link
1166 * @return null the input parameters may be modified upon return
1168 function findVariantLink( &$link, &$nt ) {
1169 $this->mConverter
->findVariantLink($link, $nt);
1173 * If a language supports multiple variants, converts text
1174 * into an array of all possible variants of the text:
1175 * 'variant' => text in that variant
1178 function convertLinkToAllVariants($text){
1179 return $this->mConverter
->convertLinkToAllVariants($text);
1184 * returns language specific options used by User::getPageRenderHash()
1185 * for example, the preferred language variant
1190 function getExtraHashOptions() {
1191 return $this->mConverter
->getExtraHashOptions();
1195 * for languages that support multiple variants, the title of an
1196 * article may be displayed differently in different variants. this
1197 * function returns the apporiate title defined in the body of the article.
1201 function getParsedTitle() {
1202 return $this->mConverter
->getParsedTitle();
1206 * Enclose a string with the "no conversion" tag. This is used by
1207 * various functions in the Parser
1209 * @param string $text text to be tagged for no conversion
1210 * @return string the tagged text
1212 function markNoConversion( $text ) {
1213 return $this->mConverter
->markNoConversion( $text );
1217 * A regular expression to match legal word-trailing characters
1218 * which should be merged onto a link of the form [[foo]]bar.
1223 function linkTrail() {
1224 return $this->getMessage( 'linktrail' );
1227 function getLangObj() {
1232 * Get the RFC 3066 code for this language object
1234 function getCode() {
1235 return str_replace( '_', '-', strtolower( substr( get_class( $this ), 8 ) ) );
1241 # FIXME: Merge all UTF-8 support code into Language base class.
1242 # We no longer support Latin-1 charset.
1243 require_once( 'LanguageUtf8.php' );
1245 # This should fail gracefully if there's not a localization available
1246 wfSuppressWarnings();
1247 // Preload base classes to work around APC/PHP5 bug
1248 include_once( 'Language' . str_replace( '-', '_', ucfirst( $wgLanguageCode ) ) . '.deps.php' );
1249 include_once( 'Language' . str_replace( '-', '_', ucfirst( $wgLanguageCode ) ) . '.php' );
1250 wfRestoreWarnings();