2003-08-14 Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
[mono.git] / mcs / class / System.XML / Mono.Xml.Xsl.Operations / XslNumber.cs
1 //
2 // XslNumber.cs
3 //
4 // Authors:
5 //      Ben Maurer (bmaurer@users.sourceforge.net)
6 //      Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
7 //      
8 // (C) 2003 Ben Maurer
9 // (C) 2003 Atsushi Enomoto
10 //
11
12 using System;
13 using System.Collections;
14 using System.Xml;
15 using System.Xml.XPath;
16 using System.Xml.Xsl;
17
18 namespace Mono.Xml.Xsl.Operations {
19         public class XslNumber : XslCompiledElement {
20                 
21                 // <xsl:number
22                 //   level = "single" | "multiple" | "any"
23                 XslNumberingLevel level;
24                 //   count = pattern
25                 XPathExpression count;
26                 //   from = pattern
27                 XPathExpression from;
28                 //   value = number-expression
29                 XPathExpression value;
30                 //   format = { string }
31                 XslAvt format;
32                 //   lang = { nmtoken }
33                 XslAvt lang;
34                 //   letter-value = { "alphabetic" | "traditional" }
35                 XslAvt letterValue;
36                 //   grouping-separator = { char }
37                 XslAvt groupingSeparator;
38                 //   grouping-size = { number } />
39                 XslAvt groupingSize;
40                 
41                 public XslNumber (Compiler c) : base (c) {}
42                 
43                 protected override void Compile (Compiler c)
44                 {
45                         switch (c.GetAttribute ("level"))
46                         {
47                         case "single":
48                                 level = XslNumberingLevel.Single;
49                                 break;
50                         case "multiple":
51                                 level = XslNumberingLevel.Multiple;
52                                 break;
53                         case "any":
54                                 level = XslNumberingLevel.Any;
55                                 break;
56                         case null:
57                         case "":
58                         default:
59                                 level = XslNumberingLevel.Single; // single == default
60                                 break;
61                         }
62                         
63                         count = c.CompilePattern (c.GetAttribute ("count"));
64                         from = c.CompilePattern (c.GetAttribute ("from"));
65                         value = c.CompileExpression (c.GetAttribute ("value"));
66                         
67                         if (value != null && value.ReturnType != XPathResultType.Number && value.ReturnType != XPathResultType.Any)
68                                 throw new Exception ("The expression for attribute 'value' must return a number");
69                         
70                         format = c.ParseAvtAttribute ("format");
71                         lang = c.ParseAvtAttribute ("lang");
72                         letterValue = c.ParseAvtAttribute ("letter-value");
73                         groupingSeparator = c.ParseAvtAttribute ("grouping-separator");
74                         groupingSize = c.ParseAvtAttribute ("grouping-size");
75                 }
76
77                 public override void Evaluate (XslTransformProcessor p)
78                 {
79                         p.Out.WriteString (GetFormat (p));
80                 }
81                 
82                 XslNumberFormatter GetNumberFormatter (XslTransformProcessor p)
83                 {
84                         string format = "1. ";
85                         string lang = null;
86                         string letterValue = null;
87                         char groupingSeparator = '\0';
88                         int groupingSize = 0;
89                         
90                         if (this.format != null)
91                                 format = this.format.Evaluate (p);
92                         
93                         if (this.lang != null)
94                                 lang = this.lang.Evaluate (p);
95                         
96                         if (this.letterValue != null)
97                                 letterValue = this.letterValue.Evaluate (p);
98                         
99                         if (this.groupingSeparator != null)
100                                 groupingSeparator = this.groupingSeparator.Evaluate (p) [0];
101                         
102                         if (this.groupingSize != null)
103                                 groupingSize = int.Parse (this.groupingSize.Evaluate (p));
104                         
105                         return new XslNumberFormatter (format, lang, letterValue, groupingSeparator, groupingSize);
106                 }
107                 
108                 string GetFormat (XslTransformProcessor p)
109                 {
110                         XslNumberFormatter nf = GetNumberFormatter (p);
111                         
112                         if (this.value != null)
113                                 return nf.Format ((int)p.EvaluateNumber (this.value)); // TODO: Correct rounding
114                         
115                         switch (this.level) {
116                                 case XslNumberingLevel.Single:
117                                         throw new NotImplementedException ();
118                                 case XslNumberingLevel.Multiple:
119                                         throw new NotImplementedException ();
120                                 case XslNumberingLevel.Any:
121                                         throw new NotImplementedException ();
122                                 default:
123                                         throw new Exception ("Should not get here");
124                         }
125                 }
126                 
127                 class XslNumberFormatter {
128                         public XslNumberFormatter (string format, string lang, string letterValue, char groupingSeparator, int groupingSize)
129                         {
130                                 throw new NotImplementedException ();
131                         }
132                         
133                         public int NumbersNeeded {
134                                 get { throw new NotImplementedException (); }
135                         }
136                         
137                         // return the format for a single value, ie, if using Single or Any
138                         public string Format (int value)
139                         {
140                                 throw new NotImplementedException ();
141                         }
142                         
143                         // format for an array of numbers.
144                         public string Format (int [] values)
145                         {
146                                 throw new NotImplementedException ();
147                         }
148                 }
149         }
150         
151         public enum XslNumberingLevel
152         {
153                 Single,
154                 Multiple,
155                 Any
156         }
157 }