Index: branches/REL1_18/extensions/ParserFunctions/convertTests.txt |
— | — | @@ -1,3 +1,7 @@ |
| 2 | +!! functionhooks |
| 3 | +convert |
| 4 | +!! endfunctionhooks |
| 5 | + |
2 | 6 | !! test |
3 | 7 | Simple conversion |
4 | 8 | !! input |
— | — | @@ -3,5 +7,5 @@ |
4 | 8 | {{#convert: 10 m | km }} |
5 | 9 | !!result |
6 | | -<p>0.01 kilometers |
| 10 | +<p>0.01 kilometres |
7 | 11 | </p> |
8 | 12 | !! end |
— | — | @@ -19,14 +23,14 @@ |
20 | 24 | *{{#convert: 10.0E2 km | m }} |
21 | 25 | *{{#convert: 10.0E2.5 km | m }} |
22 | 26 | !! result |
23 | | -<ul><li>0.01 kilometers |
24 | | -</li><li>0.01kilometers |
25 | | -</li><li>10,000 meters |
26 | | -</li><li>10,000-meters |
27 | | -</li><li>1,000,000 meters |
28 | | -</li><li>100 meters |
29 | | -</li><li>1,000,000 meters |
30 | | -</li><li>1,000,000.5,000 meters |
| 27 | +<ul><li>0.01 kilometres |
| 28 | +</li><li>0.01kilometres |
| 29 | +</li><li>10,000 metres |
| 30 | +</li><li>10,000-metres |
| 31 | +</li><li>1,000,000 metres |
| 32 | +</li><li>100 metres |
| 33 | +</li><li>1,000,000 metres |
| 34 | +</li><li>1,000,000.5,000 metres |
31 | 35 | </li></ul> |
32 | 36 | |
33 | 37 | !! end |
— | — | @@ -46,17 +50,17 @@ |
47 | 51 | *{{#convert: 19 m | km }} |
48 | 52 | *{{#convert: 20 m | km }} |
49 | 53 | !! result |
50 | | -<ul><li>0.01 kilometers |
51 | | -</li><li>0.011 kilometers |
52 | | -</li><li>0.012 kilometers |
53 | | -</li><li>0.013 kilometers |
54 | | -</li><li>0.014 kilometers |
55 | | -</li><li>0.015 kilometers |
56 | | -</li><li>0.016 kilometers |
57 | | -</li><li>0.017 kilometers |
58 | | -</li><li>0.018 kilometers |
59 | | -</li><li>0.019 kilometers |
60 | | -</li><li>0.02 kilometers |
| 54 | +<ul><li>0.01 kilometres |
| 55 | +</li><li>0.011 kilometres |
| 56 | +</li><li>0.012 kilometres |
| 57 | +</li><li>0.013 kilometres |
| 58 | +</li><li>0.014 kilometres |
| 59 | +</li><li>0.015 kilometres |
| 60 | +</li><li>0.016 kilometres |
| 61 | +</li><li>0.017 kilometres |
| 62 | +</li><li>0.018 kilometres |
| 63 | +</li><li>0.019 kilometres |
| 64 | +</li><li>0.02 kilometres |
61 | 65 | </li></ul> |
62 | 66 | |
63 | 67 | !! end |
— | — | @@ -73,14 +77,14 @@ |
74 | 78 | *{{#convert: 10.6 m | km }} |
75 | 79 | *{{#convert: 10.7 m | km }} |
76 | 80 | !! result |
77 | | -<ul><li>0.0100 kilometers |
78 | | -</li><li>0.0101 kilometers |
79 | | -</li><li>0.0102 kilometers |
80 | | -</li><li>0.0103 kilometers |
81 | | -</li><li>0.0104 kilometers |
82 | | -</li><li>0.0105 kilometers |
83 | | -</li><li>0.0106 kilometers |
84 | | -</li><li>0.0107 kilometers |
| 81 | +<ul><li>0.0100 kilometres |
| 82 | +</li><li>0.0101 kilometres |
| 83 | +</li><li>0.0102 kilometres |
| 84 | +</li><li>0.0103 kilometres |
| 85 | +</li><li>0.0104 kilometres |
| 86 | +</li><li>0.0105 kilometres |
| 87 | +</li><li>0.0106 kilometres |
| 88 | +</li><li>0.0107 kilometres |
85 | 89 | </li></ul> |
86 | 90 | |
87 | 91 | !! end |
— | — | @@ -90,7 +94,7 @@ |
91 | 95 | !! input |
92 | 96 | {{#convert: 25, 26, 27, 28, 29, and 30 km }} |
93 | 97 | !! result |
94 | | -<p>25,000, 26,000, 27,000, 28,000, 29,000, and 30,000 meters |
| 98 | +<p>25,000, 26,000, 27,000, 28,000, 29,000, and 30,000 metres |
95 | 99 | </p> |
96 | 100 | !! end |
97 | 101 | |
— | — | @@ -99,7 +103,7 @@ |
100 | 104 | !! input |
101 | 105 | {{#convert: 25, 26, 27, 28, 29, and 30 miles }} |
102 | 106 | !! result |
103 | | -<p>40,000, 42,000, 43,000, 45,000, 47,000, and 50,000 meters |
| 107 | +<p>40,000, 42,000, 43,000, 45,000, 47,000, and 50,000 metres |
104 | 108 | </p> |
105 | 109 | !! end |
106 | 110 | |
— | — | @@ -108,7 +112,7 @@ |
109 | 113 | !! input |
110 | 114 | {{#convert:35000, 35E3, 35.0E3, 350E2, 3.500E4, 35000E0, 350000E-1 m | km }} |
111 | 115 | !! result |
112 | | -<p>35, 35, 35.0, 35, 35.00, 35, 35 kilometers |
| 116 | +<p>35, 35, 35.0, 35, 35.00, 35, 35 kilometres |
113 | 117 | </p> |
114 | 118 | !! end |
115 | 119 | |
— | — | @@ -120,10 +124,10 @@ |
121 | 125 | *{{#convert: 25 | #sourceunit = km | #sourceunit = mm }} |
122 | 126 | *{{#convert: 25 | #sourceunit = km | cm }} |
123 | 127 | !! result |
124 | | -<ul><li>25,000 meters |
125 | | -</li><li>25,000 meters |
126 | | -</li><li>0.025 meters |
127 | | -</li><li>2,500,000 centimeters |
| 128 | +<ul><li>25,000 metres |
| 129 | +</li><li>25,000 metres |
| 130 | +</li><li>0.025 metres |
| 131 | +</li><li>2,500,000 centimetres |
128 | 132 | </li></ul> |
129 | 133 | |
130 | 134 | !! end |
— | — | @@ -142,16 +146,16 @@ |
143 | 147 | *{{#convert: 1 mi | #sf = 5 }} |
144 | 148 | *{{#convert: 1 mi | #sf = -8 }} |
145 | 149 | !! result |
146 | | -<ul><li>1,609 meters |
147 | | -</li><li>1,609.3 meters |
148 | | -</li><li>1,600 meters |
149 | | -</li><li>1,609.344 meters |
150 | | -</li><li>0 meters |
151 | | -</li><li>2,000 meters |
152 | | -</li><li>2,000 meters |
153 | | -</li><li>1,610 meters |
154 | | -</li><li>1,609.3 meters |
155 | | -</li><li>2,000 meters |
| 150 | +<ul><li>1,609 metres |
| 151 | +</li><li>1,609.3 metres |
| 152 | +</li><li>1,600 metres |
| 153 | +</li><li>1,609.344 metres |
| 154 | +</li><li>0 metres |
| 155 | +</li><li>2,000 metres |
| 156 | +</li><li>2,000 metres |
| 157 | +</li><li>1,610 metres |
| 158 | +</li><li>1,609.3 metres |
| 159 | +</li><li>2,000 metres |
156 | 160 | </li></ul> |
157 | 161 | |
158 | 162 | !! end |
— | — | @@ -186,8 +190,8 @@ |
187 | 191 | *{{#convert: 25 km | #targetunit = #sourceunit }} |
188 | 192 | *{{#convert: 25 km | #sourceunit = #targetunit }} |
189 | 193 | !! result |
190 | | -<ul><li>25 kilometers |
191 | | -</li><li>25 kilometers |
| 194 | +<ul><li>25 kilometres |
| 195 | +</li><li>25 kilometres |
192 | 196 | </li></ul> |
193 | 197 | |
194 | 198 | !! end |
— | — | @@ -196,14 +200,14 @@ |
197 | 201 | #language |
198 | 202 | !! input |
199 | 203 | *{{#convert: 10 m | km | #language=en-gb }} |
200 | | -*{{#convert: 10m | km | #language = en-gb }} |
201 | | -*{{#convert: 10 km | m |#language=en-gb}} |
202 | | -*{{#convert: 10 Pa | mmHg | #language = en-gb }} |
| 204 | +*{{#convert: 10m | km | #language = en }} |
| 205 | +*{{#convert: 10 km | m |#language=en}} |
| 206 | +*{{#convert: 10 Pa | mmHg | #language = fr }} |
203 | 207 | !! result |
204 | 208 | <ul><li>0.01 kilometres |
205 | | -</li><li>0.01kilometres |
206 | | -</li><li>10,000 metres |
207 | | -</li><li>0.1 millimetres of mercury |
| 209 | +</li><li>0.01kilometers |
| 210 | +</li><li>10,000 meters |
| 211 | +</li><li>0.1 millimètre de mercure |
208 | 212 | </li></ul> |
209 | 213 | |
210 | 214 | !! end |
— | — | @@ -217,10 +221,10 @@ |
218 | 222 | *{{#convert: 10 Pa | mmHg }} |
219 | 223 | *{{#convert: 10 pa | mmHg }} |
220 | 224 | !! result |
221 | | -<ul><li>0.01 meters |
222 | | -</li><li>10,000,000 meters |
223 | | -</li><li>0.01 megameters |
224 | | -</li><li>0.1 millimeters of mercury |
| 225 | +<ul><li>0.01 metres |
| 226 | +</li><li>10,000,000 metres |
| 227 | +</li><li>0.01 megametres |
| 228 | +</li><li>0.1 millimetres of mercury |
225 | 229 | </li><li><strong class="error">Error: unknown unit "pa"</strong> |
226 | 230 | </li></ul> |
227 | 231 | |
Index: branches/REL1_18/extensions/ParserFunctions/Convert.php |
— | — | @@ -24,8 +24,14 @@ |
25 | 25 | # A regex *FRAGMENT* which matches SI prefixes |
26 | 26 | const PREFIX_REGEX = '[YZEPTGMkh(da)dcm\x{03BC}\x{00B5}npfazy]?'; |
27 | 27 | |
28 | | - # ConvertUnit objects |
| 28 | + /** |
| 29 | + * @var ConvertUnit |
| 30 | + */ |
29 | 31 | protected $sourceUnit; |
| 32 | + |
| 33 | + /** |
| 34 | + * @var ConvertUnit |
| 35 | + */ |
30 | 36 | protected $targetUnit; |
31 | 37 | |
32 | 38 | # Whether to abbreviate the output unit |
— | — | @@ -48,6 +54,9 @@ |
49 | 55 | # The last value converted, which will be used for PLURAL evaluation |
50 | 56 | protected $lastValue; |
51 | 57 | |
| 58 | + /** |
| 59 | + * Reset the parser so it isn't contaminated by the results of previous parses |
| 60 | + */ |
52 | 61 | public function clearState(){ |
53 | 62 | # Make sure we break any references set up in the parameter passing below |
54 | 63 | unset( $this->sourceUnit ); |
— | — | @@ -176,6 +185,11 @@ |
177 | 186 | return $this->processString( $string ); |
178 | 187 | } |
179 | 188 | |
| 189 | + /** |
| 190 | + * Find the unit at the end of the string and load $this->sourceUnit with an appropriate |
| 191 | + * ConvertUnit, or throw an exception if the unit is unrecognised. |
| 192 | + * @param $string |
| 193 | + */ |
180 | 194 | protected function deduceSourceUnit( $string ){ |
181 | 195 | # Get the unit from the end of the string |
182 | 196 | $matches = array(); |
— | — | @@ -191,6 +205,7 @@ |
192 | 206 | /** |
193 | 207 | * Identify the values to be converted, and convert them |
194 | 208 | * @param $string String |
| 209 | + * @return String |
195 | 210 | */ |
196 | 211 | protected function processString( $string ){ |
197 | 212 | # Replace values |
— | — | @@ -216,7 +231,7 @@ |
217 | 232 | * Express a value in the $sourceUnit in terms of the $targetUnit, preserving |
218 | 233 | * an appropriate degree of accuracy. |
219 | 234 | * @param $value String |
220 | | - * @return void |
| 235 | + * @return String |
221 | 236 | */ |
222 | 237 | public function convert( $value ){ |
223 | 238 | global $wgContLang; |
— | — | @@ -374,6 +389,11 @@ |
375 | 390 | public $value; |
376 | 391 | protected $name; |
377 | 392 | |
| 393 | + /** |
| 394 | + * Constructor |
| 395 | + * @param $var ConvertDimension|Int a dimension constant or existing unit |
| 396 | + * @param $var2 ConvertDimension|Int optionally another dimension constant for a compound unit $var/$var2 |
| 397 | + */ |
378 | 398 | public function __construct( $var, $var2=null ){ |
379 | 399 | static $legalDimensionsFlip; |
380 | 400 | |
— | — | @@ -418,8 +438,8 @@ |
419 | 439 | if( in_array( $this->value, array_keys( self::$legalDimensions ) ) ){ |
420 | 440 | $this->name = self::$legalDimensions[$this->value]; |
421 | 441 | $this->compoundName = array( |
422 | | - self::$legalDimensions[$var], |
423 | | - self::$legalDimensions[$var2], |
| 442 | + self::$legalDimensions[$dim], |
| 443 | + self::$legalDimensions[$dim2], |
424 | 444 | ); |
425 | 445 | } else { |
426 | 446 | # Some combinations of units are fine (carats per bushel is a perfectly good, |
— | — | @@ -442,6 +462,8 @@ |
443 | 463 | |
444 | 464 | /** |
445 | 465 | * Get the name, or names, of the dimension |
| 466 | + * @param $expandCompound Bool Whether to return a string instead of an array of strings in |
| 467 | + * case of a compound unit |
446 | 468 | * @return String|Array of String |
447 | 469 | */ |
448 | 470 | public function getName( $expandCompound = false ){ |
— | — | @@ -630,7 +652,9 @@ |
631 | 653 | |
632 | 654 | /***************** MEMBER VARIABLES *****************/ |
633 | 655 | |
634 | | - # @var ConvertDimension |
| 656 | + /** |
| 657 | + * @var ConvertDimension |
| 658 | + */ |
635 | 659 | public $dimension; |
636 | 660 | |
637 | 661 | # What number you need to multiply this unit by to get the equivalent |
— | — | @@ -665,6 +689,10 @@ |
666 | 690 | $this->parseUnit( $rawUnit ); |
667 | 691 | } |
668 | 692 | |
| 693 | + /** |
| 694 | + * Parse a raw unit string, and populate member variables |
| 695 | + * @param $rawUnit String |
| 696 | + */ |
669 | 697 | protected function parseUnit( $rawUnit ){ |
670 | 698 | |
671 | 699 | # Do mappings like 'mph' --> 'mi/h' |
— | — | @@ -724,12 +752,39 @@ |
725 | 753 | } |
726 | 754 | } |
727 | 755 | |
| 756 | + /** |
| 757 | + * Get the mathematical factor which will convert a measurement in this unit into a |
| 758 | + * measurement in the SI base unit for the dimension |
| 759 | + * @return double |
| 760 | + */ |
728 | 761 | public function getConversion(){ |
729 | | - return $this->prefix |
730 | | - ? $this->conversion * self::$prefixes[$this->prefix][0] |
731 | | - : $this->conversion; |
| 762 | + return $this->conversion * $this->getPrefixConversion(); |
732 | 763 | } |
733 | 764 | |
| 765 | + /** |
| 766 | + * Get the conversion factor associated with the prefix(es) in the unit |
| 767 | + * @return double |
| 768 | + */ |
| 769 | + public function getPrefixConversion(){ |
| 770 | + if( !$this->prefix ){ |
| 771 | + return 1; |
| 772 | + } elseif( is_array( $this->prefix ) ){ |
| 773 | + $x = $this->prefix[0] !== null |
| 774 | + ? self::$prefixes[$this->prefix[0]][0] |
| 775 | + : 1; |
| 776 | + if( $this->prefix[1] !== null ){ |
| 777 | + $x *= self::$prefixes[$this->prefix[1]][0]; |
| 778 | + } |
| 779 | + return $x; |
| 780 | + } else { |
| 781 | + return self::$prefixes[$this->prefix][0]; |
| 782 | + } |
| 783 | + } |
| 784 | + |
| 785 | + /** |
| 786 | + * Get a regular expression which will match keywords for this unit |
| 787 | + * @return String |
| 788 | + */ |
734 | 789 | public function getRegex(){ |
735 | 790 | return $this->regex; |
736 | 791 | } |
— | — | @@ -738,6 +793,7 @@ |
739 | 794 | * Get the text of the unit |
740 | 795 | * @param $value String number for PLURAL support |
741 | 796 | * @param $link Bool |
| 797 | + * @param $abbreviate Bool |
742 | 798 | * @param $language Language |
743 | 799 | * @return String |
744 | 800 | */ |
— | — | @@ -785,7 +841,19 @@ |
786 | 842 | return trim( $msgText ); |
787 | 843 | } |
788 | 844 | |
789 | | - protected function getTextFromMessage( $dimension, $unit, $prefix, $number, $link, $abbreviate, $language ){ |
| 845 | + /** |
| 846 | + * Retrieve the unit text from actual messages |
| 847 | + * @param $dimension String |
| 848 | + * @param $unit String |
| 849 | + * @param $prefix String |
| 850 | + * @param $string String |
| 851 | + * @param $number String the actual value (for {{PLURAL}} etc) |
| 852 | + * @param $link Bool |
| 853 | + * @param $abbreviate Bool |
| 854 | + * @param $language Language|Bool|null |
| 855 | + * @return String |
| 856 | + */ |
| 857 | + protected function getTextFromMessage( $dimension, $unit, $prefix, $string, $number, $link, $abbreviate, $language ){ |
790 | 858 | $abbr = $abbreviate ? '-abbr' : ''; |
791 | 859 | $prefix = $prefix === null |
792 | 860 | ? '' |
Index: branches/REL1_18/extensions/ParserFunctions/ParserFunctions.php |
— | — | @@ -29,6 +29,23 @@ |
30 | 30 | */ |
31 | 31 | $wgPFEnableStringFunctions = false; |
32 | 32 | |
| 33 | +/** |
| 34 | + * Enable Convert parser for converting between units of measurement |
| 35 | + */ |
| 36 | +$wgPFEnableConvert = false; |
| 37 | + |
| 38 | +/** |
| 39 | + * The language for 'en' is actually 'en-us', which insists on using non-canonical translations |
| 40 | + * of the SI base units ("meter" rather than "metre" and "liter" rather than "litre"). We |
| 41 | + * can avoid contaminatng dialects by internally mapping languages by default; this is |
| 42 | + * configurable so you can remove it if you like, or add other maps if that's useful. |
| 43 | + * Essentially, if your wiki's $wgContLang appears as a key in this array, the value is |
| 44 | + * what is used as the default language for {{#convert}} output. |
| 45 | + */ |
| 46 | +$wgPFUnitLanguageVariants = array( |
| 47 | + 'en' => 'en-gb' |
| 48 | +); |
| 49 | + |
33 | 50 | /** REGISTRATION */ |
34 | 51 | $wgExtensionCredits['parserhook'][] = array( |
35 | 52 | 'path' => __FILE__, |
— | — | @@ -53,7 +70,7 @@ |
54 | 71 | $wgHooks['ParserFirstCallInit'][] = 'wfRegisterParserFunctions'; |
55 | 72 | |
56 | 73 | function wfRegisterParserFunctions( $parser ) { |
57 | | - global $wgPFEnableStringFunctions; |
| 74 | + global $wgPFEnableStringFunctions, $wgPFEnableConvert; |
58 | 75 | |
59 | 76 | if ( defined( get_class( $parser ) . '::SFH_OBJECT_ARGS' ) ) { |
60 | 77 | // These functions accept DOM-style arguments |
— | — | @@ -77,7 +94,6 @@ |
78 | 95 | $parser->setFunctionHook( 'timel', 'ExtParserFunctions::localTime' ); |
79 | 96 | $parser->setFunctionHook( 'rel2abs', 'ExtParserFunctions::rel2abs' ); |
80 | 97 | $parser->setFunctionHook( 'titleparts', 'ExtParserFunctions::titleparts' ); |
81 | | - $parser->setFunctionHook( 'convert', 'ExtParserFunctions::convert' ); |
82 | 98 | |
83 | 99 | // String Functions |
84 | 100 | if ( $wgPFEnableStringFunctions ) { |
— | — | @@ -91,5 +107,9 @@ |
92 | 108 | $parser->setFunctionHook( 'urldecode', 'ExtParserFunctions::runUrlDecode' ); |
93 | 109 | } |
94 | 110 | |
| 111 | + if( $wgPFEnableConvert ) { |
| 112 | + $parser->setFunctionHook( 'convert', 'ExtParserFunctions::convert' ); |
| 113 | + } |
| 114 | + |
95 | 115 | return true; |
96 | 116 | } |
Property changes on: branches/REL1_18/extensions/ParserFunctions |
___________________________________________________________________ |
Modified: svn:mergeinfo |
97 | 117 | Merged /trunk/extensions/ParserFunctions:r96499,96502,96505 |