KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > outerj > daisy > books > publisher > impl > publicationprocess > NumeratorFormatter


1 //
2
// This file was copied from the Apache Xalan project.
3
// Irrelevant parts of it have been removed.
4
//
5
/*
6 * Copyright 1999-2004 The Apache Software Foundation.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */

20 /*
21  * $Id: NumeratorFormatter.java,v 1.8 2004/02/16 20:41:29 minchau Exp $
22  */

23 package org.outerj.daisy.books.publisher.impl.publicationprocess;
24 //package org.apache.xalan.transformer;
25

26 import java.util.Locale JavaDoc;
27 import java.util.NoSuchElementException JavaDoc;
28
29 import org.w3c.dom.Element JavaDoc;
30
31 /**
32  * Converts enumerated numbers into strings, using the XSL conversion attributes.
33  * Having this in a class helps avoid being forced to extract the attributes repeatedly.
34  */

35 class NumeratorFormatter
36 { /**
37    * Table to help in converting decimals to roman numerals.
38    * @see org.apache.xalan.transformer.DecimalToRoman
39    */

40   private final static DecimalToRoman m_romanConvertTable[] = {
41     new DecimalToRoman(1000, "M", 900, "CM"),
42     new DecimalToRoman(500, "D", 400, "CD"),
43     new DecimalToRoman(100L, "C", 90L, "XC"),
44     new DecimalToRoman(50L, "L", 40L, "XL"),
45     new DecimalToRoman(10L, "X", 9L, "IX"),
46     new DecimalToRoman(5L, "V", 4L, "IV"),
47     new DecimalToRoman(1L, "I", 1L, "I") };
48
49   /**
50    * Chars for converting integers into alpha counts.
51    */

52   private final static char[] m_alphaCountTable = { 'Z', // z for zero
53
'A', 'B', 'C', 'D', 'E',
54                                                     'F', 'G', 'H', 'I', 'J',
55                                                     'K', 'L', 'M', 'N', 'O',
56                                                     'P', 'Q', 'R', 'S', 'T',
57                                                     'U', 'V', 'W', 'X', 'Y' };
58
59   /**
60    * Convert a long integer into alphabetic counting, in other words
61    * count using the sequence A B C ... Z AA AB AC.... etc.
62    *
63    * @param val Value to convert -- must be greater than zero.
64    * @return String representing alpha count of number.
65    * @see org.apache.xalan.transformer.DecimalToRoman
66    *
67    * Note that the radix of the conversion is inferred from the size
68    * of the table.
69    */

70   public static String JavaDoc int2alphaCount(int val)
71   {
72     char[] table = m_alphaCountTable;
73     int radix = table.length;
74
75     // Create a buffer to hold the result
76
// TODO: size of the table can be detereined by computing
77
// logs of the radix. For now, we fake it.
78
char buf[] = new char[100];
79
80     // next character to set in the buffer
81
int charPos = buf.length - 1; // work backward through buf[]
82

83     // index in table of the last character that we stored
84
int lookupIndex = 1; // start off with anything other than zero to make correction work
85

86     // Correction number
87
//
88
// Correction can take on exactly two values:
89
//
90
// 0 if the next character is to be emitted is usual
91
//
92
// radix - 1
93
// if the next char to be emitted should be one less than
94
// you would expect
95
//
96
// For example, consider radix 10, where 1="A" and 10="J"
97
//
98
// In this scheme, we count: A, B, C ... H, I, J (not A0 and certainly
99
// not AJ), A1
100
//
101
// So, how do we keep from emitting AJ for 10? After correctly emitting the
102
// J, lookupIndex is zero. We now compute a correction number of 9 (radix-1).
103
// In the following line, we'll compute (val+correction) % radix, which is,
104
// (val+9)/10. By this time, val is 1, so we compute (1+9) % 10, which
105
// is 10 % 10 or zero. So, we'll prepare to emit "JJ", but then we'll
106
// later suppress the leading J as representing zero (in the mod system,
107
// it can represent either 10 or zero). In summary, the correction value of
108
// "radix-1" acts like "-1" when run through the mod operator, but with the
109
// desireable characteristic that it never produces a negative number.
110
int correction = 0;
111
112     // TODO: throw error on out of range input
113
do
114     {
115
116       // most of the correction calculation is explained above, the reason for the
117
// term after the "|| " is that it correctly propagates carries across
118
// multiple columns.
119
correction =
120         ((lookupIndex == 0) || (correction != 0 && lookupIndex == radix - 1))
121         ? (radix - 1) : 0;
122
123       // index in "table" of the next char to emit
124
lookupIndex = (val + correction) % radix;
125
126       // shift input by one "column"
127
val = (val / radix);
128
129       // if the next value we'd put out would be a leading zero, we're done.
130
if (lookupIndex == 0 && val == 0)
131         break;
132
133       // put out the next character of output
134
buf[charPos--] = table[lookupIndex];
135     }
136     while (val > 0);
137
138     return new String JavaDoc(buf, charPos + 1, (buf.length - charPos - 1));
139   }
140
141   /**
142    * Convert a long integer into roman numerals.
143    * @param val Value to convert.
144    * @param prefixesAreOK true_ to enable prefix notation (e.g. 4 = "IV"),
145    * false_ to disable prefix notation (e.g. 4 = "IIII").
146    * @return Roman numeral string.
147    * @see DecimalToRoman
148    * @see m_romanConvertTable
149    */

150   public static String JavaDoc long2roman(long val, boolean prefixesAreOK)
151   {
152
153     if (val <= 0)
154     {
155       return "#E(" + val + ")";
156     }
157
158     String JavaDoc roman = "";
159     int place = 0;
160
161     if (val <= 3999L)
162     {
163       do
164       {
165         while (val >= m_romanConvertTable[place].m_postValue)
166         {
167           roman += m_romanConvertTable[place].m_postLetter;
168           val -= m_romanConvertTable[place].m_postValue;
169         }
170
171         if (prefixesAreOK)
172         {
173           if (val >= m_romanConvertTable[place].m_preValue)
174           {
175             roman += m_romanConvertTable[place].m_preLetter;
176             val -= m_romanConvertTable[place].m_preValue;
177           }
178         }
179
180         place++;
181       }
182       while (val > 0);
183     }
184     else
185     {
186       roman = "#error";
187     }
188
189     return roman;
190   } // end long2roman
191
}
192
193 /**
194  * Structure to help in converting integers to roman numerals
195  */

196 class DecimalToRoman
197 {
198
199   /**
200    * Constructor DecimalToRoman
201    *
202    *
203    * @param postValue Minimum value for a given range of
204    * roman numbers
205    * @param postLetter Correspoding letter (roman) to postValue
206    * @param preValue Value of last prefixed number within
207    * that same range (i.e. IV if postval is 5 (V))
208    * @param preLetter Correspoding letter(roman) to preValue
209    */

210   public DecimalToRoman(long postValue, String JavaDoc postLetter, long preValue,
211                         String JavaDoc preLetter)
212   {
213
214     this.m_postValue = postValue;
215     this.m_postLetter = postLetter;
216     this.m_preValue = preValue;
217     this.m_preLetter = preLetter;
218   }
219
220   /** Minimum value for a given range of roman numbers */
221   public long m_postValue;
222
223   /** Correspoding letter (roman) to m_postValue */
224   public String JavaDoc m_postLetter;
225
226   /** Value of last prefixed number within that same range */
227   public long m_preValue;
228
229   /** Correspoding letter (roman) to m_preValue */
230   public String JavaDoc m_preLetter;
231 }
232
Popular Tags