TtsSpan.java revision b9f7692ce61a90d2735865cf040e896c004977ba
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
17package android.text.style;
18
19import java.text.NumberFormat;
20import java.util.Locale;
21
22import android.os.Parcel;
23import android.os.PersistableBundle;
24import android.text.ParcelableSpan;
25import 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 */
40public 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
465    public TtsSpan(String type, PersistableBundle args) {
466        mType = type;
467        mArgs = args;
468    }
469
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     */
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     */
487    public PersistableBundle getArgs() {
488        return mArgs;
489    }
490
491    @Override
492    public int describeContents() {
493        return 0;
494    }
495
496    @Override
497    public void writeToParcel(Parcel dest, int flags) {
498        dest.writeString(mType);
499        dest.writePersistableBundle(mArgs);
500    }
501
502    @Override
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
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         */
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")
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")
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")
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
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
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         */
1475        public VerbatimBuilder setVerbatim(String verbatim) {
1476            return setStringArgument(TtsSpan.ARG_VERBATIM, verbatim);
1477        }
1478    }
1479}
1480