1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.text.style;
18 
19 import java.text.NumberFormat;
20 import java.util.Locale;
21 
22 import android.os.Parcel;
23 import android.os.PersistableBundle;
24 import android.text.ParcelableSpan;
25 import android.text.TextUtils;
26 
27 /**
28  * A span that supplies additional meta-data for the associated text intended
29  * for text-to-speech engines. If the text is being processed by a
30  * text-to-speech engine, the engine may use the data in this span in addition
31  * to or instead of its associated text.
32  *
33  * Each instance of a TtsSpan has a type, for example {@link #TYPE_DATE}
34  * or {@link #TYPE_MEASURE}. And a list of arguments, provided as
35  * key-value pairs in a bundle.
36  *
37  * The inner classes are there for convenience and provide builders for each
38  * TtsSpan type.
39  */
40 public class TtsSpan implements ParcelableSpan {
41     private final String mType;
42     private final PersistableBundle mArgs;
43 
44     /**
45      * This span type can be used to add morphosyntactic features to the text it
46      * spans over, or synthesize a something else than the spanned text. Use
47      * the argument {@link #ARG_TEXT} to set a different text.
48      * Accepts the arguments {@link #ARG_GENDER},
49      * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
50      * {@link #ARG_CASE}.
51      */
52     public static final String TYPE_TEXT = "android.type.text";
53 
54     /**
55      * The text associated with this span is a cardinal. Must include the
56      * number to be synthesized with {@link #ARG_NUMBER}.
57      * Also accepts the arguments {@link #ARG_GENDER},
58      * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
59      * {@link #ARG_CASE}.
60      */
61     public static final String TYPE_CARDINAL = "android.type.cardinal";
62 
63     /**
64      * The text associated with this span is an ordinal. Must include the
65      * number to be synthesized with {@link #ARG_NUMBER}.
66      * Also accepts the arguments {@link #ARG_GENDER},
67      * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
68      * {@link #ARG_CASE}.
69      */
70     public static final String TYPE_ORDINAL = "android.type.ordinal";
71 
72     /**
73      * The text associated with this span is a decimal number. Must include the
74      * number to be synthesized with {@link #ARG_INTEGER_PART} and
75      * {@link #ARG_FRACTIONAL_PART}.
76      * Also accepts the arguments {@link #ARG_GENDER},
77      * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
78      * {@link #ARG_CASE}.
79      */
80     public static final String TYPE_DECIMAL = "android.type.decimal";
81 
82     /**
83      * The text associated with this span is a fractional number. Must include
84      * the number to be synthesized with {@link #ARG_NUMERATOR} and
85      * {@link #ARG_DENOMINATOR}. {@link #ARG_INTEGER_PART} is optional
86      * Also accepts the arguments {@link #ARG_GENDER},
87      * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
88      * {@link #ARG_CASE}.
89      */
90     public static final String TYPE_FRACTION = "android.type.fraction";
91 
92     /**
93      * The text associated with this span is a measure, consisting of a number
94      * and a unit. The number can be a cardinal, decimal or a fraction. Set the
95      * number with the same arguments as {@link #TYPE_CARDINAL},
96      * {@link #TYPE_DECIMAL} or {@link #TYPE_FRACTION}. The unit can be
97      * specified with {@link #ARG_UNIT}.
98      * Also accepts the arguments {@link #ARG_GENDER},
99      * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
100      * {@link #ARG_CASE}.
101      */
102     public static final String TYPE_MEASURE = "android.type.measure";
103 
104     /**
105      * The text associated with this span is a time, consisting of a number of
106      * hours and minutes, specified with {@link #ARG_HOURS} and
107      * {@link #ARG_MINUTES}.
108      * Also accepts the arguments {@link #ARG_GENDER},
109      * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
110      * {@link #ARG_CASE}.
111      */
112     public static final String TYPE_TIME = "android.type.time";
113 
114     /**
115      * The text associated with this span is a date. At least one of the
116      * arguments {@link #ARG_MONTH} and {@link #ARG_YEAR} has to be provided.
117      * The argument {@link #ARG_DAY} is optional if {@link #ARG_MONTH} is set.
118      * The argument {@link #ARG_WEEKDAY} is optional if {@link #ARG_DAY} is set.
119      * Also accepts the arguments {@link #ARG_GENDER}, {@link #ARG_ANIMACY},
120      * {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
121      */
122     public static final String TYPE_DATE = "android.type.date";
123 
124     /**
125      * The text associated with this span is a telephone number. The argument
126      * {@link #ARG_NUMBER_PARTS} is required. {@link #ARG_COUNTRY_CODE} and
127      * {@link #ARG_EXTENSION} are optional.
128      * Also accepts the arguments {@link #ARG_GENDER}, {@link #ARG_ANIMACY},
129      * {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
130      */
131     public static final String TYPE_TELEPHONE = "android.type.telephone";
132 
133     /**
134      * The text associated with this span is a URI (can be used for URLs and
135      * email addresses). The full schema for URLs, which email addresses can
136      * effectively be seen as a subset of, is:
137      * protocol://username:password@domain:port/path?query_string#fragment_id
138      * Hence populating just username and domain will read as an email address.
139      * All arguments are optional, but at least one has to be provided:
140      * {@link #ARG_PROTOCOL}, {@link #ARG_USERNAME}, {@link #ARG_PASSWORD},
141      * {@link #ARG_DOMAIN}, {@link #ARG_PORT}, {@link #ARG_PATH},
142      * {@link #ARG_QUERY_STRING} and {@link #ARG_FRAGMENT_ID}.
143      * Also accepts the arguments {@link #ARG_GENDER}, {@link #ARG_ANIMACY},
144      * {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
145      */
146     public static final String TYPE_ELECTRONIC = "android.type.electronic";
147 
148     /**
149      * The text associated with this span is an amount of money. Set the amount
150      * with the same arguments as {@link #TYPE_DECIMAL}.
151      * {@link #ARG_CURRENCY} is used to set the currency. {@link #ARG_QUANTITY}
152      * is optional.
153      * Also accepts the arguments {@link #ARG_GENDER}, {@link #ARG_ANIMACY},
154      * {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
155      */
156     public static final String TYPE_MONEY = "android.type.money";
157 
158     /**
159      * The text associated with this span is a series of digits that have to be
160      * read sequentially. The digits can be set with {@link #ARG_DIGITS}.
161      * Also accepts the arguments {@link #ARG_GENDER}, {@link #ARG_ANIMACY},
162      * {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
163      */
164     public static final String TYPE_DIGITS = "android.type.digits";
165 
166     /**
167      * The text associated with this span is a series of characters that have to
168      * be read verbatim. The engine will attempt to ready out any character like
169      * punctuation but excluding whitespace. {@link #ARG_VERBATIM} is required.
170      * Also accepts the arguments {@link #ARG_GENDER},
171      * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
172      */
173     public static final String TYPE_VERBATIM = "android.type.verbatim";
174 
175     /**
176      * String argument supplying gender information. Can be any of
177      * {@link #GENDER_NEUTRAL}, {@link #GENDER_MALE} and
178      * {@link #GENDER_FEMALE}.
179      */
180     public static final String ARG_GENDER = "android.arg.gender";
181 
182     public static final String GENDER_NEUTRAL = "android.neutral";
183     public static final String GENDER_MALE = "android.male";
184     public static final String GENDER_FEMALE = "android.female";
185 
186     /**
187      * String argument supplying animacy information. Can be
188      * {@link #ANIMACY_ANIMATE} or
189      * {@link #ANIMACY_INANIMATE}
190      */
191     public static final String ARG_ANIMACY = "android.arg.animacy";
192 
193     public static final String ANIMACY_ANIMATE = "android.animate";
194     public static final String ANIMACY_INANIMATE = "android.inanimate";
195 
196     /**
197      * String argument supplying multiplicity information. Can be any of
198      * {@link #MULTIPLICITY_SINGLE}, {@link #MULTIPLICITY_DUAL} and
199      * {@link #MULTIPLICITY_PLURAL}
200      */
201     public static final String ARG_MULTIPLICITY = "android.arg.multiplicity";
202 
203     public static final String MULTIPLICITY_SINGLE = "android.single";
204     public static final String MULTIPLICITY_DUAL = "android.dual";
205     public static final String MULTIPLICITY_PLURAL = "android.plural";
206 
207     /**
208      * String argument supplying case information. Can be any of
209      * {@link #CASE_NOMINATIVE}, {@link #CASE_ACCUSATIVE}, {@link #CASE_DATIVE},
210      * {@link #CASE_ABLATIVE}, {@link #CASE_GENITIVE}, {@link #CASE_VOCATIVE},
211      * {@link #CASE_LOCATIVE} and {@link #CASE_INSTRUMENTAL}
212      */
213     public static final String ARG_CASE = "android.arg.case";
214 
215     public static final String CASE_NOMINATIVE = "android.nominative";
216     public static final String CASE_ACCUSATIVE = "android.accusative";
217     public static final String CASE_DATIVE = "android.dative";
218     public static final String CASE_ABLATIVE = "android.ablative";
219     public static final String CASE_GENITIVE = "android.genitive";
220     public static final String CASE_VOCATIVE = "android.vocative";
221     public static final String CASE_LOCATIVE = "android.locative";
222     public static final String CASE_INSTRUMENTAL = "android.instrumental";
223 
224     /**
225      * String supplying the text to be synthesized. The synthesizer is free
226      * to decide how to interpret the text.
227      * Can be used with {@link #TYPE_TEXT}.
228      */
229     public static final String ARG_TEXT = "android.arg.text";
230 
231     /**
232      * Argument used to specify a whole number. The value can be a string of
233      * digits of any size optionally prefixed with a - or +.
234      * Can be used with {@link #TYPE_CARDINAL} and {@link #TYPE_ORDINAL}.
235      */
236     public static final String ARG_NUMBER = "android.arg.number";
237 
238     /**
239      * Argument used to specify the integer part of a decimal or fraction. The
240      * value can be a string of digits of any size optionally prefixed with
241      * a - or +.
242      * Can be used with {@link #TYPE_DECIMAL} and {@link #TYPE_FRACTION}.
243      */
244     public static final String ARG_INTEGER_PART = "android.arg.integer_part";
245 
246     /**
247      * Argument used to specify the fractional part of a decimal. The value can
248      * be a string of digits of any size.
249      * Can be used with {@link #TYPE_DECIMAL}.
250      */
251     public static final String ARG_FRACTIONAL_PART =
252         "android.arg.fractional_part";
253 
254     /**
255      * Argument used to choose the suffix (thousand, million, etc) that is used
256      * to pronounce large amounts of money. For example it can be used to
257      * disambiguate between "two thousand five hundred dollars" and
258      * "two point five thousand dollars".
259      * If implemented, engines should support at least "1000", "1000000",
260      * "1000000000" and "1000000000000".
261      * Example: if the {@link #ARG_INTEGER_PART} argument is "10", the
262      * {@link #ARG_FRACTIONAL_PART} argument is "4", the {@link #ARG_QUANTITY}
263      * argument is "1000" and the {@link #ARG_CURRENCY} argument is "usd", the
264      * TTS engine may pronounce the span as "ten point four thousand dollars".
265      * With the same example but with the quantity set as "1000000" the TTS
266      * engine may pronounce the span as "ten point four million dollars".
267      * Can be used with {@link #TYPE_MONEY}.
268      */
269     public static final String ARG_QUANTITY =
270             "android.arg.quantity";
271 
272     /**
273      * Argument used to specify the numerator of a fraction. The value can be a
274      * string of digits of any size optionally prefixed with a - or +.
275      * Can be used with {@link #TYPE_FRACTION}.
276      */
277     public static final String ARG_NUMERATOR = "android.arg.numerator";
278 
279     /**
280      * Argument used to specify the denominator of a fraction. The value can be
281      * a string of digits of any size optionally prefixed with a + or -.
282      * Can be used with {@link #TYPE_FRACTION}.
283      */
284     public static final String ARG_DENOMINATOR = "android.arg.denominator";
285 
286     /**
287      * Argument used to specify the unit of a measure. The unit should always be
288      * specified in English singular form. Prefixes may be used. Engines will do
289      * their best to pronounce them correctly in the language used. Engines are
290      * expected to at least support the most common ones like "meter", "second",
291      * "degree celsius" and "degree fahrenheit" with some common prefixes like
292      * "milli" and "kilo".
293      * Can be used with {@link #TYPE_MEASURE}.
294      */
295     public static final String ARG_UNIT = "android.arg.unit";
296 
297     /**
298      * Argument used to specify the hours of a time. The hours should be
299      * provided as an integer in the range from 0 up to and including 24.
300      * Can be used with {@link #TYPE_TIME}.
301      */
302     public static final String ARG_HOURS = "android.arg.hours";
303 
304     /**
305      * Argument used to specify the minutes of a time. The hours should be
306      * provided as an integer in the range from 0 up to and including 59.
307      * Can be used with {@link #TYPE_TIME}.
308      */
309     public static final String ARG_MINUTES = "android.arg.minutes";
310 
311     /**
312      * Argument used to specify the weekday of a date. The value should be
313      * provided as an integer and can be any of {@link #WEEKDAY_SUNDAY},
314      * {@link #WEEKDAY_MONDAY}, {@link #WEEKDAY_TUESDAY},
315      * {@link #WEEKDAY_WEDNESDAY}, {@link #WEEKDAY_THURSDAY},
316      * {@link #WEEKDAY_FRIDAY} and {@link #WEEKDAY_SATURDAY}.
317      * Can be used with {@link #TYPE_DATE}.
318      */
319     public static final String ARG_WEEKDAY = "android.arg.weekday";
320 
321     public static final int WEEKDAY_SUNDAY = 1;
322     public static final int WEEKDAY_MONDAY = 2;
323     public static final int WEEKDAY_TUESDAY = 3;
324     public static final int WEEKDAY_WEDNESDAY = 4;
325     public static final int WEEKDAY_THURSDAY = 5;
326     public static final int WEEKDAY_FRIDAY = 6;
327     public static final int WEEKDAY_SATURDAY = 7;
328 
329     /**
330      * Argument used to specify the day of the month of a date. The value should
331      * be provided as an integer in the range from 1 up to and including 31.
332      * Can be used with {@link #TYPE_DATE}.
333      */
334     public static final String ARG_DAY = "android.arg.day";
335 
336     /**
337      * Argument used to specify the month of a date. The value should be
338      * provided as an integer and can be any of {@link #MONTH_JANUARY},
339      * {@link #MONTH_FEBRUARY},  {@link #MONTH_MARCH}, {@link #MONTH_APRIL},
340      * {@link #MONTH_MAY}, {@link #MONTH_JUNE}, {@link #MONTH_JULY},
341      * {@link #MONTH_AUGUST}, {@link #MONTH_SEPTEMBER}, {@link #MONTH_OCTOBER},
342      * {@link #MONTH_NOVEMBER} and {@link #MONTH_DECEMBER}.
343      * Can be used with {@link #TYPE_DATE}.
344      */
345     public static final String ARG_MONTH = "android.arg.month";
346 
347     public static final int MONTH_JANUARY = 0;
348     public static final int MONTH_FEBRUARY = 1;
349     public static final int MONTH_MARCH = 2;
350     public static final int MONTH_APRIL = 3;
351     public static final int MONTH_MAY = 4;
352     public static final int MONTH_JUNE = 5;
353     public static final int MONTH_JULY = 6;
354     public static final int MONTH_AUGUST = 7;
355     public static final int MONTH_SEPTEMBER = 8;
356     public static final int MONTH_OCTOBER = 9;
357     public static final int MONTH_NOVEMBER = 10;
358     public static final int MONTH_DECEMBER = 11;
359 
360     /**
361      * Argument used to specify the year of a date. The value should be provided
362      * as a positive integer.
363      * Can be used with {@link #TYPE_DATE}.
364      */
365     public static final String ARG_YEAR = "android.arg.year";
366 
367     /**
368      * Argument used to specify the country code of a telephone number. Can be
369      * a string of digits optionally prefixed with a "+".
370      * Can be used with {@link #TYPE_TELEPHONE}.
371      */
372     public static final String ARG_COUNTRY_CODE = "android.arg.country_code";
373 
374     /**
375      * Argument used to specify the main number part of a telephone number. Can
376      * be a string of digits where the different parts of the telephone number
377      * can be separated with a space, '-', '/' or '.'.
378      * Can be used with {@link #TYPE_TELEPHONE}.
379      */
380     public static final String ARG_NUMBER_PARTS = "android.arg.number_parts";
381 
382     /**
383      * Argument used to specify the extension part of a telephone number. Can be
384      * a string of digits.
385      * Can be used with {@link #TYPE_TELEPHONE}.
386      */
387     public static final String ARG_EXTENSION = "android.arg.extension";
388 
389     /**
390      * Argument used to specify the protocol of a URI. Examples are "http" and
391      * "ftp".
392      * Can be used with {@link #TYPE_ELECTRONIC}.
393      */
394     public static final String ARG_PROTOCOL = "android.arg.protocol";
395 
396     /**
397      * Argument used to specify the username part of a URI. Should be set as a
398      * string.
399      * Can be used with {@link #TYPE_ELECTRONIC}.
400      */
401     public static final String ARG_USERNAME = "android.arg.username";
402 
403     /**
404      * Argument used to specify the password part of a URI. Should be set as a
405      * string.
406      * Can be used with {@link #TYPE_ELECTRONIC}.
407      */
408     public static final String ARG_PASSWORD = "android.arg.password";
409 
410     /**
411      * Argument used to specify the domain part of a URI. For example
412      * "source.android.com".
413      * Can be used with {@link #TYPE_ELECTRONIC}.
414      */
415     public static final String ARG_DOMAIN = "android.arg.domain";
416 
417     /**
418      * Argument used to specify the port number of a URI. Should be specified as
419      * an integer.
420      * Can be used with {@link #TYPE_ELECTRONIC}.
421      */
422     public static final String ARG_PORT = "android.arg.port";
423 
424     /**
425      * Argument used to specify the path part of a URI. For example
426      * "source/index.html".
427      * Can be used with {@link #TYPE_ELECTRONIC}.
428      */
429     public static final String ARG_PATH = "android.arg.path";
430 
431     /**
432      * Argument used to specify the query string of a URI. For example
433      * "arg=value&argtwo=value".
434      * Can be used with {@link #TYPE_ELECTRONIC}.
435      */
436     public static final String ARG_QUERY_STRING = "android.arg.query_string";
437 
438     /**
439      * Argument used to specify the fragment id of a URI. Should be specified as
440      * a string.
441      * Can be used with {@link #TYPE_ELECTRONIC}.
442      */
443     public static final String ARG_FRAGMENT_ID = "android.arg.fragment_id";
444 
445     /**
446      * Argument used to specify the currency. Should be a ISO4217 currency code,
447      * e.g. "USD".
448      * Can be used with {@link #TYPE_MONEY}.
449      */
450     public static final String ARG_CURRENCY = "android.arg.money";
451 
452     /**
453      * Argument used to specify a string of digits.
454      * Can be used with {@link #TYPE_DIGITS}.
455      */
456     public static final String ARG_DIGITS = "android.arg.digits";
457 
458     /**
459      * Argument used to specify a string where the characters are read verbatim,
460      * except whitespace.
461      * Can be used with {@link #TYPE_VERBATIM}.
462      */
463     public static final String ARG_VERBATIM = "android.arg.verbatim";
464 
TtsSpan(String type, PersistableBundle args)465     public TtsSpan(String type, PersistableBundle args) {
466         mType = type;
467         mArgs = args;
468     }
469 
TtsSpan(Parcel src)470     public TtsSpan(Parcel src) {
471         mType = src.readString();
472         mArgs = src.readPersistableBundle();
473     }
474 
475     /**
476      * Returns the type.
477      * @return The type of this instance.
478      */
getType()479     public String getType() {
480         return mType;
481     }
482 
483     /**
484      * Returns a bundle of the arguments set.
485      * @return The bundle of the arguments set.
486      */
getArgs()487     public PersistableBundle getArgs() {
488         return mArgs;
489     }
490 
491     @Override
describeContents()492     public int describeContents() {
493         return 0;
494     }
495 
496     @Override
writeToParcel(Parcel dest, int flags)497     public void writeToParcel(Parcel dest, int flags) {
498         dest.writeString(mType);
499         dest.writePersistableBundle(mArgs);
500     }
501 
502     @Override
getSpanTypeId()503     public int getSpanTypeId() {
504         return TextUtils.TTS_SPAN;
505     }
506 
507     /**
508      * A simple builder for TtsSpans.
509      * This builder can be used directly, but the more specific subclasses of
510      * this builder like {@link TtsSpan.TextBuilder} and
511      * {@link TtsSpan.CardinalBuilder} are likely more useful.
512      *
513      * This class uses generics so methods from this class can return instances
514      * of its child classes, resulting in a fluent API (CRTP pattern).
515      */
516     public static class Builder<C extends Builder<?>> {
517         // Holds the type of this class.
518         private final String mType;
519 
520         // Holds the arguments of this class. It only stores objects of type
521         // String, Integer and Long.
522         private PersistableBundle mArgs = new PersistableBundle();
523 
Builder(String type)524         public Builder(String type) {
525             mType = type;
526         }
527 
528         /**
529          * Returns a TtsSpan built from the parameters set by the setter
530          * methods.
531          * @return A TtsSpan built with parameters of this builder.
532          */
build()533         public TtsSpan build() {
534             return new TtsSpan(mType, mArgs);
535         }
536 
537         /**
538          * Sets an argument to a string value.
539          * @param arg The argument name.
540          * @param value The value the argument should be set to.
541          * @return This instance.
542          */
543         @SuppressWarnings("unchecked")
setStringArgument(String arg, String value)544         public C setStringArgument(String arg, String value) {
545             mArgs.putString(arg, value);
546             return (C) this;
547         }
548 
549         /**
550          * Sets an argument to an int value.
551          * @param arg The argument name.
552          * @param value The value the argument should be set to.
553          */
554         @SuppressWarnings("unchecked")
setIntArgument(String arg, int value)555         public C setIntArgument(String arg, int value) {
556             mArgs.putInt(arg, value);
557             return (C) this;
558         }
559 
560         /**
561          * Sets an argument to a long value.
562          * @param arg The argument name.
563          * @param value The value the argument should be set to.
564          */
565         @SuppressWarnings("unchecked")
setLongArgument(String arg, long value)566         public C setLongArgument(String arg, long value) {
567             mArgs.putLong(arg, value);
568             return (C) this;
569         }
570     }
571 
572     /**
573      * A builder for TtsSpans, has setters for morphosyntactic features.
574      * This builder can be used directly, but the more specific subclasses of
575      * this builder like {@link TtsSpan.TextBuilder} and
576      * {@link TtsSpan.CardinalBuilder} are likely more useful.
577      */
578     public static class SemioticClassBuilder<C extends SemioticClassBuilder<?>>
579             extends Builder<C> {
580 
SemioticClassBuilder(String type)581         public SemioticClassBuilder(String type) {
582             super(type);
583         }
584 
585         /**
586          * Sets the gender information for this instance.
587          * @param gender Can any of {@link #GENDER_NEUTRAL},
588          *     {@link #GENDER_MALE} and {@link #GENDER_FEMALE}.
589          * @return This instance.
590          */
setGender(String gender)591         public C setGender(String gender) {
592             return setStringArgument(TtsSpan.ARG_GENDER, gender);
593         }
594 
595         /**
596          * Sets the animacy information for this instance.
597          * @param animacy Can be any of {@link #ANIMACY_ANIMATE} and
598          *     {@link #ANIMACY_INANIMATE}.
599          * @return This instance.
600          */
setAnimacy(String animacy)601         public C setAnimacy(String animacy) {
602             return setStringArgument(TtsSpan.ARG_ANIMACY, animacy);
603         }
604 
605         /**
606          * Sets the multiplicity information for this instance.
607          * @param multiplicity Can be any of
608          *     {@link #MULTIPLICITY_SINGLE}, {@link #MULTIPLICITY_DUAL} and
609          *     {@link #MULTIPLICITY_PLURAL}.
610          * @return This instance.
611          */
setMultiplicity(String multiplicity)612         public C setMultiplicity(String multiplicity) {
613             return setStringArgument(TtsSpan.ARG_MULTIPLICITY, multiplicity);
614         }
615 
616         /**
617          * Sets the grammatical case information for this instance.
618          * @param grammaticalCase Can be any of {@link #CASE_NOMINATIVE},
619          *     {@link #CASE_ACCUSATIVE}, {@link #CASE_DATIVE},
620          *     {@link #CASE_ABLATIVE}, {@link #CASE_GENITIVE},
621          *     {@link #CASE_VOCATIVE}, {@link #CASE_LOCATIVE} and
622          *     {@link #CASE_INSTRUMENTAL}.
623          * @return This instance.
624          */
setCase(String grammaticalCase)625         public C setCase(String grammaticalCase) {
626             return setStringArgument(TtsSpan.ARG_CASE, grammaticalCase);
627         }
628     }
629 
630     /**
631      * A builder for TtsSpans of type {@link #TYPE_TEXT}.
632      */
633     public static class TextBuilder extends SemioticClassBuilder<TextBuilder> {
634 
635         /**
636          * Creates a builder for a TtsSpan of type {@link #TYPE_TEXT}.
637          */
TextBuilder()638         public TextBuilder() {
639             super(TtsSpan.TYPE_TEXT);
640         }
641 
642         /**
643          * Creates a TtsSpan of type {@link #TYPE_TEXT} and sets the
644          * {@link #ARG_TEXT} argument.
645          * @param text The text to be synthesized.
646          * @see #setText(String)
647          */
TextBuilder(String text)648         public TextBuilder(String text) {
649             this();
650             setText(text);
651         }
652 
653         /**
654          * Sets the {@link #ARG_TEXT} argument, the text to be synthesized.
655          * @param text The string that will be synthesized.
656          * @return This instance.
657          */
setText(String text)658         public TextBuilder setText(String text) {
659             return setStringArgument(TtsSpan.ARG_TEXT, text);
660         }
661     }
662 
663     /**
664      * A builder for TtsSpans of type {@link #TYPE_CARDINAL}.
665      */
666     public static class CardinalBuilder
667             extends SemioticClassBuilder<CardinalBuilder> {
668 
669         /**
670          * Creates a builder for a TtsSpan of type {@link #TYPE_CARDINAL}.
671          */
CardinalBuilder()672         public CardinalBuilder() {
673             super(TtsSpan.TYPE_CARDINAL);
674         }
675 
676         /**
677          * Creates a TtsSpan of type {@link #TYPE_CARDINAL} and sets the
678          * {@link #ARG_NUMBER} argument.
679          * @param number The number to synthesize.
680          * @see #setNumber(long)
681          */
CardinalBuilder(long number)682         public CardinalBuilder(long number) {
683             this();
684             setNumber(number);
685         }
686 
687         /**
688          * Creates a TtsSpan of type {@link #TYPE_CARDINAL} and sets the
689          * {@link #ARG_NUMBER} argument.
690          * @param number The number to synthesize.
691          * @see #setNumber(String)
692          */
CardinalBuilder(String number)693         public CardinalBuilder(String number) {
694             this();
695             setNumber(number);
696         }
697 
698         /**
699          * Convenience method that converts the number to a String and set it to
700          * the value for {@link #ARG_NUMBER}.
701          * @param number The number that will be synthesized.
702          * @return This instance.
703          */
setNumber(long number)704         public CardinalBuilder setNumber(long number) {
705             return setNumber(String.valueOf(number));
706         }
707 
708         /**
709          * Sets the {@link #ARG_NUMBER} argument.
710          * @param number A non-empty string of digits with an optional
711          *     leading + or -.
712          * @return This instance.
713          */
setNumber(String number)714         public CardinalBuilder setNumber(String number) {
715             return setStringArgument(TtsSpan.ARG_NUMBER, number);
716         }
717     }
718 
719     /**
720      * A builder for TtsSpans of type {@link #TYPE_ORDINAL}.
721      */
722     public static class OrdinalBuilder
723             extends SemioticClassBuilder<OrdinalBuilder> {
724 
725         /**
726          * Creates a builder for a TtsSpan of type {@link #TYPE_ORDINAL}.
727          */
OrdinalBuilder()728         public OrdinalBuilder() {
729             super(TtsSpan.TYPE_ORDINAL);
730         }
731 
732         /**
733          * Creates a TtsSpan of type {@link #TYPE_ORDINAL} and sets the
734          * {@link #ARG_NUMBER} argument.
735          * @param number The ordinal number to synthesize.
736          * @see #setNumber(long)
737          */
OrdinalBuilder(long number)738         public OrdinalBuilder(long number) {
739             this();
740             setNumber(number);
741         }
742 
743         /**
744          * Creates a TtsSpan of type {@link #TYPE_ORDINAL} and sets the
745          * {@link #ARG_NUMBER} argument.
746          * @param number The number to synthesize.
747          * @see #setNumber(String)
748          */
OrdinalBuilder(String number)749         public OrdinalBuilder(String number) {
750             this();
751             setNumber(number);
752         }
753 
754         /**
755          * Convenience method that converts the number to a String and sets it
756          * to the value for {@link #ARG_NUMBER}.
757          * @param number The ordinal number that will be synthesized.
758          * @return This instance.
759          */
setNumber(long number)760         public OrdinalBuilder setNumber(long number) {
761             return setNumber(String.valueOf(number));
762         }
763 
764         /**
765          * Sets the {@link #ARG_NUMBER} argument.
766          * @param number A non-empty string of digits with an optional
767          *     leading + or -.
768          * @return This instance.
769          */
setNumber(String number)770         public OrdinalBuilder setNumber(String number) {
771             return setStringArgument(TtsSpan.ARG_NUMBER, number);
772         }
773     }
774 
775     /**
776      * A builder for TtsSpans of type {@link #TYPE_DECIMAL}.
777      */
778     public static class DecimalBuilder
779             extends SemioticClassBuilder<DecimalBuilder> {
780 
781         /**
782          * Creates a builder for a TtsSpan of type {@link #TYPE_DECIMAL}.
783          */
DecimalBuilder()784         public DecimalBuilder() {
785             super(TtsSpan.TYPE_DECIMAL);
786         }
787 
788         /**
789          * Creates a TtsSpan of type {@link #TYPE_DECIMAL} and sets the
790          * {@link #ARG_INTEGER_PART} and {@link #ARG_FRACTIONAL_PART} arguments.
791          * @see {@link #setArgumentsFromDouble(double, int, int)
792          */
DecimalBuilder(double number, int minimumFractionDigits, int maximumFractionDigits)793         public DecimalBuilder(double number,
794                               int minimumFractionDigits,
795                               int maximumFractionDigits) {
796             this();
797             setArgumentsFromDouble(number,
798                                    minimumFractionDigits,
799                                    maximumFractionDigits);
800         }
801 
802         /**
803          * Creates a TtsSpan of type {@link #TYPE_DECIMAL} and sets the
804          * {@link #ARG_INTEGER_PART} and {@link #ARG_FRACTIONAL_PART} arguments.
805          */
DecimalBuilder(String integerPart, String fractionalPart)806         public DecimalBuilder(String integerPart, String fractionalPart) {
807             this();
808             setIntegerPart(integerPart);
809             setFractionalPart(fractionalPart);
810         }
811 
812         /**
813          * Convenience method takes a double and a maximum number of fractional
814          * digits, it sets the {@link #ARG_INTEGER_PART} and
815          * {@link #ARG_FRACTIONAL_PART} arguments.
816          * @param number The number to be synthesized.
817          * @param minimumFractionDigits The minimum number of fraction digits
818          *     that are pronounced.
819          * @param maximumFractionDigits The maximum number of fraction digits
820          *     that are pronounced. If maximumFractionDigits <
821          *     minimumFractionDigits then minimumFractionDigits will be assumed
822          *     to be equal to maximumFractionDigits.
823          * @return This instance.
824          */
setArgumentsFromDouble( double number, int minimumFractionDigits, int maximumFractionDigits)825         public DecimalBuilder setArgumentsFromDouble(
826                 double number,
827                 int minimumFractionDigits,
828                 int maximumFractionDigits) {
829             // Format double.
830             NumberFormat formatter = NumberFormat.getInstance(Locale.US);
831             formatter.setMinimumFractionDigits(maximumFractionDigits);
832             formatter.setMaximumFractionDigits(maximumFractionDigits);
833             formatter.setGroupingUsed(false);
834             String str = formatter.format(number);
835 
836             // Split at decimal point.
837             int i = str.indexOf('.');
838             if (i >= 0) {
839                 setIntegerPart(str.substring(0, i));
840                 setFractionalPart(str.substring(i + 1));
841             } else {
842                 setIntegerPart(str);
843             }
844             return this;
845         }
846 
847         /**
848          * Convenience method that converts the number to a String and sets it
849          * to the value for {@link #ARG_INTEGER_PART}.
850          * @param integerPart The integer part of the decimal.
851          * @return This instance.
852          */
setIntegerPart(long integerPart)853         public DecimalBuilder setIntegerPart(long integerPart) {
854             return setIntegerPart(String.valueOf(integerPart));
855         }
856 
857         /**
858          * Sets the {@link #ARG_INTEGER_PART} argument.
859          * @param integerPart A non-empty string of digits with an optional
860          *     leading + or -.
861          * @return This instance.
862          */
setIntegerPart(String integerPart)863         public DecimalBuilder setIntegerPart(String integerPart) {
864             return setStringArgument(TtsSpan.ARG_INTEGER_PART, integerPart);
865         }
866 
867         /**
868          * Sets the {@link #ARG_FRACTIONAL_PART} argument.
869          * @param fractionalPart A non-empty string of digits.
870          * @return This instance.
871          */
setFractionalPart(String fractionalPart)872         public DecimalBuilder setFractionalPart(String fractionalPart) {
873             return setStringArgument(TtsSpan.ARG_FRACTIONAL_PART,
874                                      fractionalPart);
875         }
876     }
877 
878     /**
879      * A builder for TtsSpans of type {@link #TYPE_FRACTION}.
880      */
881     public static class FractionBuilder
882             extends SemioticClassBuilder<FractionBuilder> {
883 
884         /**
885          * Creates a builder for a TtsSpan of type {@link #TYPE_FRACTION}.
886          */
FractionBuilder()887         public FractionBuilder() {
888             super(TtsSpan.TYPE_FRACTION);
889         }
890 
891         /**
892          * Creates a TtsSpan of type {@link #TYPE_FRACTION} and sets the
893          * {@link #ARG_INTEGER_PART}, {@link #ARG_NUMERATOR}, and
894          * {@link #ARG_DENOMINATOR} arguments.
895          */
FractionBuilder(long integerPart, long numerator, long denominator)896         public FractionBuilder(long integerPart,
897                                long numerator,
898                                long denominator) {
899             this();
900             setIntegerPart(integerPart);
901             setNumerator(numerator);
902             setDenominator(denominator);
903         }
904 
905         /**
906          * Convenience method that converts the integer to a String and sets the
907          * argument {@link #ARG_NUMBER}.
908          * @param integerPart The integer part.
909          * @return This instance.
910          */
setIntegerPart(long integerPart)911         public FractionBuilder setIntegerPart(long integerPart) {
912             return setIntegerPart(String.valueOf(integerPart));
913         }
914 
915         /**
916          * Sets the {@link #ARG_INTEGER_PART} argument.
917          * @param integerPart A non-empty string of digits with an optional
918          *     leading + or -.
919          * @return This instance.
920          */
setIntegerPart(String integerPart)921         public FractionBuilder setIntegerPart(String integerPart) {
922             return setStringArgument(TtsSpan.ARG_INTEGER_PART, integerPart);
923         }
924 
925         /**
926          * Convenience method that converts the numerator to a String and sets
927          * the argument {@link #ARG_NUMERATOR}.
928          * @param numerator The numerator.
929          * @return This instance.
930          */
setNumerator(long numerator)931         public FractionBuilder setNumerator(long numerator) {
932             return setNumerator(String.valueOf(numerator));
933         }
934 
935         /**
936          * Sets the {@link #ARG_NUMERATOR} argument.
937          * @param numerator A non-empty string of digits with an optional
938          *     leading + or -.
939          * @return This instance.
940          */
setNumerator(String numerator)941         public FractionBuilder setNumerator(String numerator) {
942             return setStringArgument(TtsSpan.ARG_NUMERATOR, numerator);
943         }
944 
945         /**
946          * Convenience method that converts the denominator to a String and sets
947          * the argument {@link #ARG_DENOMINATOR}.
948          * @param denominator The denominator.
949          * @return This instance.
950          */
setDenominator(long denominator)951         public FractionBuilder setDenominator(long denominator) {
952             return setDenominator(String.valueOf(denominator));
953         }
954 
955         /**
956          * Sets the {@link #ARG_DENOMINATOR} argument.
957          * @param denominator A non-empty string of digits with an optional
958          *     leading + or -.
959          * @return This instance.
960          */
setDenominator(String denominator)961         public FractionBuilder setDenominator(String denominator) {
962             return setStringArgument(TtsSpan.ARG_DENOMINATOR, denominator);
963         }
964     }
965 
966     /**
967      * A builder for TtsSpans of type {@link #TYPE_MEASURE}.
968      */
969     public static class MeasureBuilder
970             extends SemioticClassBuilder<MeasureBuilder> {
971 
972         /**
973          * Creates a builder for a TtsSpan of type {@link #TYPE_MEASURE}.
974          */
MeasureBuilder()975         public MeasureBuilder() {
976             super(TtsSpan.TYPE_MEASURE);
977         }
978 
979         /**
980          * Convenience method that converts the number to a String and set it to
981          * the value for {@link #ARG_NUMBER}.
982          * @param number The amount of the measure.
983          * @return This instance.
984          */
setNumber(long number)985         public MeasureBuilder setNumber(long number) {
986             return setNumber(String.valueOf(number));
987         }
988 
989         /**
990          * Sets the {@link #ARG_NUMBER} argument.
991          * @param number A non-empty string of digits with an optional
992          *     leading + or -.
993          * @return This instance.
994          */
setNumber(String number)995         public MeasureBuilder setNumber(String number) {
996             return setStringArgument(TtsSpan.ARG_NUMBER, number);
997         }
998 
999         /**
1000          * Convenience method that converts the integer part to a String and set
1001          * it to the value for {@link #ARG_INTEGER_PART}.
1002          * @param integerPart The integer part of a decimal or fraction.
1003          * @return This instance.
1004          */
setIntegerPart(long integerPart)1005         public MeasureBuilder setIntegerPart(long integerPart) {
1006             return setNumber(String.valueOf(integerPart));
1007         }
1008 
1009         /**
1010          * Sets the {@link #ARG_INTEGER_PART} argument.
1011          * @param integerPart The integer part of a decimal or fraction; a
1012          * non-empty string of digits with an optional
1013          *     leading + or -.
1014          * @return This instance.
1015          */
setIntegerPart(String integerPart)1016         public MeasureBuilder setIntegerPart(String integerPart) {
1017             return setStringArgument(TtsSpan.ARG_INTEGER_PART, integerPart);
1018         }
1019 
1020         /**
1021          * Sets the {@link #ARG_FRACTIONAL_PART} argument.
1022          * @param fractionalPart The fractional part of a decimal; a non-empty
1023          *     string of digits with an optional leading + or -.
1024          * @return This instance.
1025          */
setFractionalPart(String fractionalPart)1026         public MeasureBuilder setFractionalPart(String fractionalPart) {
1027             return setStringArgument(TtsSpan.ARG_FRACTIONAL_PART,
1028                                      fractionalPart);
1029         }
1030 
1031         /**
1032          * Convenience method that converts the numerator to a String and set it
1033          * to the value for {@link #ARG_NUMERATOR}.
1034          * @param numerator The numerator of a fraction.
1035          * @return This instance.
1036          */
setNumerator(long numerator)1037         public MeasureBuilder setNumerator(long numerator) {
1038             return setNumerator(String.valueOf(numerator));
1039         }
1040 
1041         /**
1042          * Sets the {@link #ARG_NUMERATOR} argument.
1043          * @param numerator The numerator of a fraction; a non-empty string of
1044          *     digits with an optional leading + or -.
1045          * @return This instance.
1046          */
setNumerator(String numerator)1047         public MeasureBuilder setNumerator(String numerator) {
1048             return setStringArgument(TtsSpan.ARG_NUMERATOR, numerator);
1049         }
1050 
1051         /**
1052          * Convenience method that converts the denominator to a String and set
1053          * it to the value for {@link #ARG_DENOMINATOR}.
1054          * @param denominator The denominator of a fraction.
1055          * @return This instance.
1056          */
setDenominator(long denominator)1057         public MeasureBuilder setDenominator(long denominator) {
1058             return setDenominator(String.valueOf(denominator));
1059         }
1060 
1061         /**
1062          * Sets the {@link #ARG_DENOMINATOR} argument.
1063          * @param denominator The denominator of a fraction; a non-empty string
1064          *     of digits with an optional leading + or -.
1065          * @return This instance.
1066          */
setDenominator(String denominator)1067         public MeasureBuilder setDenominator(String denominator) {
1068             return setStringArgument(TtsSpan.ARG_DENOMINATOR, denominator);
1069         }
1070 
1071         /**
1072          * Sets the {@link #ARG_UNIT} argument.
1073          * @param unit The unit of the measure.
1074          * @return This instance.
1075          * @see {@link TtsSpan.ARG_UNIT}
1076          */
setUnit(String unit)1077         public MeasureBuilder setUnit(String unit) {
1078             return setStringArgument(TtsSpan.ARG_UNIT, unit);
1079         }
1080     }
1081 
1082     /**
1083      * A builder for TtsSpans of type {@link #TYPE_TIME}.
1084      */
1085     public static class TimeBuilder
1086             extends SemioticClassBuilder<TimeBuilder> {
1087 
1088         /**
1089          * Creates a builder for a TtsSpan of type {@link #TYPE_TIME}.
1090          */
TimeBuilder()1091         public TimeBuilder() {
1092             super(TtsSpan.TYPE_TIME);
1093         }
1094 
1095         /**
1096          * Creates a builder for a TtsSpan of type {@link #TYPE_TIME} and
1097          * sets the {@link #ARG_HOURS} and {@link #ARG_MINUTES} arguments.
1098          */
TimeBuilder(int hours, int minutes)1099         public TimeBuilder(int hours, int minutes) {
1100             this();
1101             setHours(hours);
1102             setMinutes(minutes);
1103         }
1104 
1105         /**
1106          * Sets the {@link #ARG_HOURS} argument.
1107          * @param hours The value to be set for hours. See {@link #ARG_HOURS}.
1108          * @return This instance.
1109          * @see {@link #ARG_HOURS}
1110          */
setHours(int hours)1111         public TimeBuilder setHours(int hours) {
1112             return setIntArgument(TtsSpan.ARG_HOURS, hours);
1113         }
1114 
1115         /**
1116          * Sets the {@link #ARG_MINUTES} argument.
1117          * @param minutes The value to be set for minutes. See
1118          *     {@link #ARG_MINUTES}.
1119          * @return This instance.
1120          * @see {@link #ARG_MINUTES}
1121          */
setMinutes(int minutes)1122         public TimeBuilder setMinutes(int minutes) {
1123             return setIntArgument(TtsSpan.ARG_MINUTES, minutes);
1124         }
1125     }
1126 
1127     /**
1128      * A builder for TtsSpans of type {@link #TYPE_DATE}.
1129      */
1130     public static class DateBuilder
1131             extends SemioticClassBuilder<DateBuilder> {
1132 
1133         /**
1134          * Creates a builder for a TtsSpan of type {@link #TYPE_DATE}.
1135          */
DateBuilder()1136         public DateBuilder() {
1137             super(TtsSpan.TYPE_DATE);
1138         }
1139 
1140         /**
1141          * Creates a builder for a TtsSpan of type {@link #TYPE_TIME} and
1142          * possibly sets the {@link #ARG_WEEKDAY}, {@link #ARG_DAY},
1143          * {@link #ARG_MONTH} and {@link #ARG_YEAR} arguments. Pass null to any
1144          * argument to leave it unset.
1145          */
DateBuilder(Integer weekday, Integer day, Integer month, Integer year)1146         public DateBuilder(Integer weekday,
1147                            Integer day,
1148                            Integer month,
1149                            Integer year) {
1150             this();
1151             if (weekday != null) {
1152                 setWeekday(weekday);
1153             }
1154             if (day != null) {
1155                 setDay(day);
1156             }
1157             if (month != null) {
1158                 setMonth(month);
1159             }
1160             if (year != null) {
1161                 setYear(year);
1162             }
1163         }
1164 
1165         /**
1166          * Sets the {@link #ARG_WEEKDAY} argument.
1167          * @param weekday The value to be set for weekday. See
1168          *     {@link #ARG_WEEKDAY}.
1169          * @return This instance.
1170          * @see {@link #ARG_WEEKDAY}
1171          */
setWeekday(int weekday)1172         public DateBuilder setWeekday(int weekday) {
1173             return setIntArgument(TtsSpan.ARG_WEEKDAY, weekday);
1174         }
1175 
1176         /**
1177          * Sets the {@link #ARG_DAY} argument.
1178          * @param day The value to be set for day. See {@link #ARG_DAY}.
1179          * @return This instance.
1180          * @see {@link #ARG_DAY}
1181          */
setDay(int day)1182         public DateBuilder setDay(int day) {
1183             return setIntArgument(TtsSpan.ARG_DAY, day);
1184         }
1185 
1186         /**
1187          * Sets the {@link #ARG_MONTH} argument.
1188          * @param month The value to be set for month. See {@link #ARG_MONTH}.
1189          * @return This instance.
1190          * @see {@link #ARG_MONTH}
1191          */
setMonth(int month)1192         public DateBuilder setMonth(int month) {
1193             return setIntArgument(TtsSpan.ARG_MONTH, month);
1194         }
1195 
1196         /**
1197          * Sets the {@link #ARG_YEAR} argument.
1198          * @param year The value to be set for year. See {@link #ARG_YEAR}.
1199          * @return This instance.
1200          * @see {@link #ARG_YEAR}
1201          */
setYear(int year)1202         public DateBuilder setYear(int year) {
1203             return setIntArgument(TtsSpan.ARG_YEAR, year);
1204         }
1205     }
1206 
1207     /**
1208      * A builder for TtsSpans of type {@link #TYPE_MONEY}.
1209      */
1210     public static class MoneyBuilder
1211             extends SemioticClassBuilder<MoneyBuilder> {
1212 
1213         /**
1214          * Creates a TtsSpan of type {@link #TYPE_MONEY}.
1215          */
MoneyBuilder()1216         public MoneyBuilder() {
1217             super(TtsSpan.TYPE_MONEY);
1218         }
1219 
1220         /**
1221          * Convenience method that converts the number to a String and set it to
1222          * the value for {@link #ARG_INTEGER_PART}.
1223          * @param integerPart The integer part of the amount.
1224          * @return This instance.
1225          */
setIntegerPart(long integerPart)1226         public MoneyBuilder setIntegerPart(long integerPart) {
1227             return setIntegerPart(String.valueOf(integerPart));
1228         }
1229 
1230         /**
1231          * Sets the {@link #ARG_INTEGER_PART} argument.
1232          * @param integerPart A non-empty string of digits with an optional
1233          *     leading + or -.
1234          * @return This instance.
1235          */
setIntegerPart(String integerPart)1236         public MoneyBuilder setIntegerPart(String integerPart) {
1237             return setStringArgument(TtsSpan.ARG_INTEGER_PART, integerPart);
1238         }
1239 
1240         /**
1241          * Sets the {@link #ARG_FRACTIONAL_PART} argument.
1242          * @param fractionalPart Can be a string of digits of any size.
1243          * @return This instance.
1244          */
setFractionalPart(String fractionalPart)1245         public MoneyBuilder setFractionalPart(String fractionalPart) {
1246             return setStringArgument(TtsSpan.ARG_FRACTIONAL_PART, fractionalPart);
1247         }
1248 
1249         /**
1250          * Sets the {@link #ARG_CURRENCY} argument.
1251          * @param currency Should be a ISO4217 currency code, e.g. "USD".
1252          * @return This instance.
1253          */
setCurrency(String currency)1254         public MoneyBuilder setCurrency(String currency) {
1255             return setStringArgument(TtsSpan.ARG_CURRENCY, currency);
1256         }
1257 
1258         /**
1259          * Sets the {@link #ARG_QUANTITY} argument.
1260          * @param quantity
1261          * @return This instance.
1262          */
setQuantity(String quantity)1263         public MoneyBuilder setQuantity(String quantity) {
1264             return setStringArgument(TtsSpan.ARG_QUANTITY, quantity);
1265         }
1266     }
1267 
1268     /**
1269      * A builder for TtsSpans of type {@link #TYPE_TELEPHONE}.
1270      */
1271     public static class TelephoneBuilder
1272             extends SemioticClassBuilder<TelephoneBuilder> {
1273 
1274         /**
1275          * Creates a TtsSpan of type {@link #TYPE_TELEPHONE}.
1276          */
TelephoneBuilder()1277         public TelephoneBuilder() {
1278             super(TtsSpan.TYPE_TELEPHONE);
1279         }
1280 
1281         /**
1282          * Creates a TtsSpan of type {@link #TYPE_TELEPHONE} and sets the
1283          * {@link #ARG_NUMBER_PARTS} argument.
1284          */
TelephoneBuilder(String numberParts)1285         public TelephoneBuilder(String numberParts) {
1286             this();
1287             setNumberParts(numberParts);
1288         }
1289 
1290         /**
1291          * Sets the {@link #ARG_COUNTRY_CODE} argument.
1292          * @param countryCode The country code can be a series of digits
1293          * optionally prefixed with a "+".
1294          * @return This instance.
1295          */
setCountryCode(String countryCode)1296         public TelephoneBuilder setCountryCode(String countryCode) {
1297             return setStringArgument(TtsSpan.ARG_COUNTRY_CODE, countryCode);
1298         }
1299 
1300         /**
1301          * Sets the {@link #ARG_NUMBER_PARTS} argument.
1302          * @param numberParts The main telephone number. Can be a series of
1303          *     digits and letters separated by spaces, "/", "-" or ".".
1304          * @return This instance.
1305          */
setNumberParts(String numberParts)1306         public TelephoneBuilder setNumberParts(String numberParts) {
1307             return setStringArgument(TtsSpan.ARG_NUMBER_PARTS, numberParts);
1308         }
1309 
1310         /**
1311          * Sets the {@link #ARG_EXTENSION} argument.
1312          * @param extension The extension can be a series of digits.
1313          * @return This instance.
1314          */
setExtension(String extension)1315         public TelephoneBuilder setExtension(String extension) {
1316             return setStringArgument(TtsSpan.ARG_EXTENSION, extension);
1317         }
1318     }
1319 
1320     /**
1321      * A builder for TtsSpans of type {@link #TYPE_ELECTRONIC}.
1322      */
1323     public static class ElectronicBuilder
1324             extends SemioticClassBuilder<ElectronicBuilder> {
1325 
1326         /**
1327          * Creates a TtsSpan of type {@link #TYPE_ELECTRONIC}.
1328          */
ElectronicBuilder()1329         public ElectronicBuilder() {
1330             super(TtsSpan.TYPE_ELECTRONIC);
1331         }
1332 
1333         /**
1334          * Sets the {@link #ARG_USERNAME} and {@link #ARG_DOMAIN}
1335          *     arguments, representing an email address.
1336          * @param username The part before the @ in the email address.
1337          * @param domain The part after the @ in the email address.
1338          * @return This instance.
1339          */
setEmailArguments(String username, String domain)1340         public ElectronicBuilder setEmailArguments(String username,
1341                                                    String domain) {
1342             return setDomain(domain).setUsername(username);
1343         }
1344 
1345         /**
1346          * Sets the {@link #ARG_PROTOCOL} argument.
1347          * @param protocol The protocol of the URI. Examples are "http" and
1348          *     "ftp".
1349          * @return This instance.
1350          */
setProtocol(String protocol)1351         public ElectronicBuilder setProtocol(String protocol) {
1352             return setStringArgument(TtsSpan.ARG_PROTOCOL, protocol);
1353         }
1354 
1355         /**
1356          * Sets the {@link #ARG_USERNAME} argument.
1357          * @return This instance.
1358          */
setUsername(String username)1359         public ElectronicBuilder setUsername(String username) {
1360             return setStringArgument(TtsSpan.ARG_USERNAME, username);
1361         }
1362 
1363         /**
1364          * Sets the {@link #ARG_PASSWORD} argument.
1365          * @return This instance.
1366          */
setPassword(String password)1367         public ElectronicBuilder setPassword(String password) {
1368             return setStringArgument(TtsSpan.ARG_PASSWORD, password);
1369         }
1370 
1371         /**
1372          * Sets the {@link #ARG_DOMAIN} argument.
1373          * @param domain The domain, for example "source.android.com".
1374          * @return This instance.
1375          */
setDomain(String domain)1376         public ElectronicBuilder setDomain(String domain) {
1377             return setStringArgument(TtsSpan.ARG_DOMAIN, domain);
1378         }
1379 
1380         /**
1381          * Sets the {@link #ARG_PORT} argument.
1382          * @return This instance.
1383          */
setPort(int port)1384         public ElectronicBuilder setPort(int port) {
1385             return setIntArgument(TtsSpan.ARG_PORT, port);
1386         }
1387 
1388         /**
1389          * Sets the {@link #ARG_PATH} argument.
1390          * @param path For example "source/index.html".
1391          * @return This instance.
1392          */
setPath(String path)1393         public ElectronicBuilder setPath(String path) {
1394             return setStringArgument(TtsSpan.ARG_PATH, path);
1395         }
1396 
1397         /**
1398          * Sets the {@link #ARG_QUERY_STRING} argument.
1399          * @param queryString For example "arg=value&argtwo=value".
1400          * @return This instance.
1401          */
setQueryString(String queryString)1402         public ElectronicBuilder setQueryString(String queryString) {
1403             return setStringArgument(TtsSpan.ARG_QUERY_STRING, queryString);
1404         }
1405 
1406         /**
1407          * Sets the {@link #ARG_FRAGMENT_ID} argument.
1408          * @return This instance.
1409          */
setFragmentId(String fragmentId)1410         public ElectronicBuilder setFragmentId(String fragmentId) {
1411             return setStringArgument(TtsSpan.ARG_FRAGMENT_ID, fragmentId);
1412         }
1413     }
1414 
1415     /**
1416      * A builder for TtsSpans of type {@link #TYPE_DIGITS}.
1417      */
1418     public static class DigitsBuilder
1419             extends SemioticClassBuilder<DigitsBuilder> {
1420 
1421         /**
1422          * Creates a builder for a TtsSpan of type {@link #TYPE_DIGITS}.
1423          */
DigitsBuilder()1424         public DigitsBuilder() {
1425             super(TtsSpan.TYPE_DIGITS);
1426         }
1427 
1428         /**
1429          * Creates a builder for a TtsSpan of type {@link #TYPE_DIGITS}
1430          * and sets the {@link #ARG_DIGITS} argument.
1431          */
DigitsBuilder(String digits)1432         public DigitsBuilder(String digits) {
1433             this();
1434             setDigits(digits);
1435         }
1436 
1437         /**
1438          * Sets the {@link #ARG_DIGITS} argument.
1439          * @param digits A string of digits.
1440          * @return This instance.
1441          */
setDigits(String digits)1442         public DigitsBuilder setDigits(String digits) {
1443             return setStringArgument(TtsSpan.ARG_DIGITS, digits);
1444         }
1445     }
1446 
1447     /**
1448      * A builder for TtsSpans of type {@link #TYPE_VERBATIM}.
1449      */
1450     public static class VerbatimBuilder
1451             extends SemioticClassBuilder<VerbatimBuilder> {
1452 
1453         /**
1454          * Creates a builder for a TtsSpan of type {@link #TYPE_VERBATIM}.
1455          */
VerbatimBuilder()1456         public VerbatimBuilder() {
1457             super(TtsSpan.TYPE_VERBATIM);
1458         }
1459 
1460         /**
1461          * Creates a builder for a TtsSpan of type {@link #TYPE_VERBATIM}
1462          * and sets the {@link #ARG_VERBATIM} argument.
1463          */
VerbatimBuilder(String verbatim)1464         public VerbatimBuilder(String verbatim) {
1465             this();
1466             setVerbatim(verbatim);
1467         }
1468 
1469         /**
1470          * Sets the {@link #ARG_VERBATIM} argument.
1471          * @param verbatim A string of characters that will be read verbatim,
1472          *     except whitespace.
1473          * @return This instance.
1474          */
setVerbatim(String verbatim)1475         public VerbatimBuilder setVerbatim(String verbatim) {
1476             return setStringArgument(TtsSpan.ARG_VERBATIM, verbatim);
1477         }
1478     }
1479 }
1480