TtsSpan.java revision b1a092c772e2799c02c4da8b7fc28e43b4119ae4
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 android.os.Parcel;
20import android.os.PersistableBundle;
21import android.text.ParcelableSpan;
22import android.text.TextUtils;
23
24/**
25 * A span that supplies additional meta-data for the associated text intended
26 * for text-to-speech engines.  If the text is being processed by a
27 * text-to-speech engine, the engine may use the data in this span in addition
28 * to or instead of its associated text.
29 *
30 * The inner classes are there for convenience and provide builders for each
31 * TtsSpan type.
32 */
33public class TtsSpan implements ParcelableSpan {
34    private final String mType;
35    private final PersistableBundle mArgs;
36
37    /**
38     * This span type can be used to add morphosyntactic features to the text it
39     * spans over, or synthesize a something else than the spanned text.  Use
40     * the argument {@link #ARG_TEXT} to set a different text.
41     * Accepts the arguments {@link #ARG_GENDER},
42     * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
43     * {@link #ARG_CASE}.
44     */
45    public static final String TYPE_TEXT = "android.type.text";
46
47    /**
48     * The text associated with this span is a cardinal.  Must include the
49     * number to be synthesized with {@link #ARG_NUMBER}.
50     * Also accepts the arguments {@link #ARG_GENDER},
51     * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
52     * {@link #ARG_CASE}.
53     */
54    public static final String TYPE_CARDINAL = "android.type.cardinal";
55
56    /**
57     * The text associated with this span is an ordinal. Must include the
58     * number to be synthesized with {@link #ARG_NUMBER}.
59     * Also accepts the arguments {@link #ARG_GENDER},
60     * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
61     * {@link #ARG_CASE}.
62     */
63    public static final String TYPE_ORDINAL = "android.type.ordinal";
64
65    /**
66     * The text associated with this span is a decimal number. Must include the
67     * number to be synthesized with {@link #ARG_INTEGER_PART} and
68     * {@link #ARG_FRACTIONAL_PART}.
69     * Also accepts the arguments {@link #ARG_GENDER},
70     * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
71     * {@link #ARG_CASE}.
72     */
73    public static final String TYPE_DECIMAL = "android.type.decimal";
74
75    /**
76     * The text associated with this span is a fractional number. Must include
77     * the number to be synthesized with {@link #ARG_NUMERATOR} and
78     * {@link #ARG_DENOMINATOR}. {@link #ARG_INTEGER_PART} is optional
79     * Also accepts the arguments {@link #ARG_GENDER},
80     * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
81     * {@link #ARG_CASE}.
82     */
83    public static final String TYPE_FRACTION = "android.type.fraction";
84
85    /**
86     * The text associated with this span is a measure, consisting of a number
87     * and a unit. The number can be a cardinal, decimal or a fraction. Set the
88     * number with the same arguments as {@link #TYPE_CARDINAL},
89     * {@link #TYPE_DECIMAL} or {@link #TYPE_FRACTION}. The unit can be
90     * specified with {@link #ARG_UNIT}.
91     * Also accepts the arguments {@link #ARG_GENDER},
92     * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
93     * {@link #ARG_CASE}.
94     */
95    public static final String TYPE_MEASURE = "android.type.measure";
96
97    /**
98     * The text associated with this span is a time, consisting of a number of
99     * hours and minutes, specified with {@link #ARG_HOURS} and
100     * {@link #ARG_MINUTES}.
101     * Also accepts the arguments {@link #ARG_GENDER},
102     * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
103     * {@link #ARG_CASE}.
104     */
105    public static final String TYPE_TIME = "android.type.time";
106
107    /**
108     * The text associated with this span is a date. All arguments are optional,
109     * but at least one has to be provided: {@link #ARG_WEEKDAY},
110     * {@link #ARG_DAY}, {@link #ARG_MONTH} and {@link #ARG_YEAR}.
111     * Also accepts the arguments {@link #ARG_GENDER},
112     * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
113     * {@link #ARG_CASE}.
114     */
115    public static final String TYPE_DATE = "android.type.date";
116
117    /**
118     * The text associated with this span is a telephone number. The argument
119     * {@link #ARG_NUMBER_PART} is required. {@link #ARG_COUNTRY_CODE} and
120     * {@link #ARG_EXTENSION} are optional.
121     * Also accepts the arguments {@link #ARG_GENDER},
122     * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
123     * {@link #ARG_CASE}.
124     */
125    public static final String TYPE_TELEPHONE = "android.type.telephone";
126
127
128    /**
129     * The text associated with this span is a URI (can be used for URLs and
130     * email addresses). The full schema for URLs, which email addresses can
131     * effectively be seen as a subset of, is:
132     * protocol://username:password@domain:port/path?query_string#fragment_id
133     * Hence populating just username and domain will read as an email address.
134     * All arguments are optional, but at least one has to be provided:
135     * {@link #ARG_PROTOCOL}, {@link #ARG_USERNAME}, {@link #ARG_PASSWORD},
136     * {@link #ARG_DOMAIN}, {@link #ARG_PORT}, {@link #ARG_PATH},
137     * {@link #ARG_QUERY_STRING} and {@link #ARG_FRAGMENT_ID}.
138     * Also accepts the arguments {@link #ARG_GENDER},
139     * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
140     * {@link #ARG_CASE}.
141     */
142    public static final String TYPE_ELECTRONIC = "android.type.electronic";
143
144    /**
145     * The text associated with this span is an amount of money. Set the amount
146     * with the same arguments as {@link #TYPE_DECIMAL}.
147     * {@link #ARG_CURRENCY} is used to set the currency. {@link #ARG_QUANTITY}
148     * is optional.
149     * Also accepts the arguments {@link #ARG_GENDER},
150     * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
151     * {@link #ARG_CASE}.
152     */
153    public static final String TYPE_MONEY = "android.type.money";
154
155    /**
156     * The text associated with this span is a series of digits that have to be
157     * read sequentially. {@link #ARG_DIGITS} is required.
158     * Also accepts the arguments {@link #ARG_GENDER},
159     * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
160     * {@link #ARG_CASE}.
161     */
162    public static final String TYPE_DIGITS = "android.type.digits";
163
164    /**
165     * The text associated with this span is a series of characters that have to
166     * be read verbatim. The engine will attempt to ready out any character like
167     * punctuation but excluding whitespace. {@link #ARG_VERBATIM} is required.
168     * Also accepts the arguments {@link #ARG_GENDER},
169     * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
170     * {@link #ARG_CASE}.
171     */
172    public static final String TYPE_VERBATIM = "android.type.verbatim";
173
174    /**
175     * String argument supplying gender information.  Can be any of
176     * {@link #GENDER_NEUTRAL}, {@link #GENDER_MALE} and
177     * {@link #GENDER_FEMALE}.
178     */
179    public static final String ARG_GENDER = "android.arg.gender";
180
181    public static final String GENDER_NEUTRAL = "android.neutral";
182    public static final String GENDER_MALE = "android.male";
183    public static final String GENDER_FEMALE = "android.female";
184
185    /**
186     * String argument supplying animacy information.  Can be
187     * {@link #ANIMACY_ANIMATE} or
188     * {@link #ANIMACY_INANIMATE}
189     */
190    public static final String ARG_ANIMACY = "android.arg.animacy";
191
192    public static final String ANIMACY_ANIMATE = "android.animate";
193    public static final String ANIMACY_INANIMATE = "android.inanimate";
194
195    /**
196     * String argument supplying multiplicity information.  Can be any of
197     * {@link #MULTIPLICITY_SINGLE},
198     * {@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},
210     * {@link #CASE_DATIVE}, {@link #CASE_ABLATIVE},
211     * {@link #CASE_GENITIVE}, {@link #CASE_VOCATIVE},
212     * {@link #CASE_LOCATIVE} and
213     * {@link #CASE_INSTRUMENTAL}
214     */
215    public static final String ARG_CASE = "android.arg.case";
216
217    public static final String CASE_NOMINATIVE = "android.nomative";
218    public static final String CASE_ACCUSATIVE = "android.accusative";
219    public static final String CASE_DATIVE = "android.dative";
220    public static final String CASE_ABLATIVE = "android.ablative";
221    public static final String CASE_GENITIVE = "android.genitive";
222    public static final String CASE_VOCATIVE = "android.vocative";
223    public static final String CASE_LOCATIVE = "android.locative";
224    public static final String CASE_INSTRUMENTAL = "android.instrumental";
225
226    /**
227     * String supplying the text to be synthesized.  The synthesizer is free
228     * to decide how to interpret the text.
229     * Can be used with {@link #TYPE_TEXT}.
230     */
231    public static final String ARG_TEXT = "android.arg.text";
232
233    /**
234     * Argument used to specify a whole number.  The value can be a string of
235     * digits of any size optionally prefixed with a - or +.
236     * Can be used with {@link #TYPE_CARDINAL} and {@link #TYPE_ORDINAL}.
237     */
238    public static final String ARG_NUMBER = "android.arg.number";
239
240    /**
241     * Argument used to specify the integer part of a decimal or fraction. The
242     * value can be a string of digits of any size optionally prefixed with a - or +.
243     * Can be used with {@link #TYPE_DECIMAL} and {@link #TYPE_FRACTION}.
244     */
245    public static final String ARG_INTEGER_PART = "android.arg.integer_part";
246
247    /**
248     * Argument used to specify the fractional part of a decimal. The value can
249     * be a string of digits of any size.
250     * Can be used with {@link #TYPE_DECIMAL}.
251     */
252    public static final String ARG_FRACTIONAL_PART =
253        "android.arg.fractional_part";
254
255    /**
256     * Argument used to choose the suffix (thousand, million, etc) that is used
257     * to pronounce large amounts of money. For example it can be used to
258     * disambiguate between "two thousand five hundred dollars" and
259     * "two point five thousand dollars".
260     * If implemented, engines should support at least "1000", "1000000",
261     * "1000000000" and "1000000000000".
262     * Example: if the {@link #ARG_INTEGER_PART} argument is "10", the
263     * {@link #ARG_FRACTIONAL_PART} argument is "4", the {@link #ARG_QUANTITY}
264     * argument is "1000" and the {@link #ARG_CURRENCY} argument is "usd", the
265     * TTS engine may pronounce the span as "ten point four thousand dollars".
266     * With the same example but with the quantity set as "1000000" the TTS
267     * engine may pronounce the span as "ten point four million dollars".
268     * Can be used with {@link #TYPE_MONEY}.
269     */
270    public static final String ARG_QUANTITY =
271            "android.arg.quantity";
272
273    /**
274     * Argument used to specify the numerator of a fraction. The value can be a
275     * string of digits of any size optionally prefixed with a - or +.
276     * Can be used with {@link #TYPE_FRACTION}.
277     */
278    public static final String ARG_NUMERATOR = "android.arg.numerator";
279
280    /**
281     * Argument used to specify the denominator of a fraction. The value can be
282     * a string of digits of any size optionally prefixed with a + or -.
283     * Can be used with {@link #TYPE_FRACTION}.
284     */
285    public static final String ARG_DENOMINATOR = "android.arg.denominator";
286
287    /**
288     * Argument used to specify the unit of a measure. The unit should always be
289     * specified in English singular form. Prefixes may be used. Engines will do
290     * their best to pronounce them correctly in the language used. Engines are
291     * expected to at least support the most common ones like "meter", "second",
292     * "degree celcius" and "degree fahrenheit" with some common prefixes like
293     * "milli" and "kilo".
294     * Can be used with {@link #TYPE_MEASURE}.
295     */
296    public static final String ARG_UNIT = "android.arg.unit";
297
298    /**
299     * Argument used to specify the hours of a time. The hours should be
300     * provided as an integer in the range from 0 up to and including 24.
301     * Can be used with {@link #TYPE_TIME}.
302     */
303    public static final String ARG_HOURS = "android.arg.hours";
304
305    /**
306     * Argument used to specify the minutes of a time. The hours should be
307     * provided as an integer in the range from 0 up to and including 59.
308     * Can be used with {@link #TYPE_TIME}.
309     */
310    public static final String ARG_MINUTES = "android.arg.minutes";
311
312    /**
313     * Argument used to specify the weekday of a date. The value should be
314     * provided as an integer and can be any of {@link #WEEKDAY_SUNDAY},
315     * {@link #WEEKDAY_MONDAY}, {@link #WEEKDAY_TUESDAY},
316     * {@link #WEEKDAY_WEDNESDAY}, {@link #WEEKDAY_THURSDAY},
317     * {@link #WEEKDAY_FRIDAY} and {@link #WEEKDAY_SATURDAY}.
318     * Can be used with {@link #TYPE_DATE}.
319     */
320    public static final String ARG_WEEKDAY = "android.arg.weekday";
321
322    public static final int WEEKDAY_SUNDAY = 1;
323    public static final int WEEKDAY_MONDAY = 2;
324    public static final int WEEKDAY_TUESDAY = 3;
325    public static final int WEEKDAY_WEDNESDAY = 4;
326    public static final int WEEKDAY_THURSDAY = 5;
327    public static final int WEEKDAY_FRIDAY = 6;
328    public static final int WEEKDAY_SATURDAY = 7;
329
330    /**
331     * Argument used to specify the day of the month of a date. The value should
332     * be provided as an integer in the range from 1 up to and including 31.
333     * Can be used with {@link #TYPE_DATE}.
334     */
335    public static final String ARG_DAY = "android.arg.day";
336
337    /**
338     * Argument used to specify the month of a date. The value should be
339     * provided as an integer and can be any of {@link #MONTH_JANUARY},
340     * {@link #MONTH_FEBRUARY},  {@link #MONTH_MARCH}, {@link #MONTH_APRIL}, {@link #MONTH_MAY},
341     * {@link #MONTH_JUNE}, {@link #MONTH_JULY}, {@link #MONTH_AUGUST}, {@link #MONTH_SEPTEMBER},
342     * {@link #MONTH_OCTOBER}, {@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.
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.
377     * Can be used with {@link #TYPE_TELEPHONE}.
378     */
379    public static final String ARG_NUMBER_PART = "android.arg.number_part";
380
381    /**
382     * Argument used to specify the extension part of a telephone number. Can be
383     * a string of digits.
384     * Can be used with {@link #TYPE_TELEPHONE}.
385     */
386    public static final String ARG_EXTENSION = "android.arg.extension";
387
388    /**
389     * Argument used to specify the protocol of a URI. Examples are "http" and
390     * "ftp".
391     * Can be used with {@link #TYPE_ELECTRONIC}.
392     */
393    public static final String ARG_PROTOCOL = "android.arg.protocol";
394
395    /**
396     * Argument used to specify the username part of a URI. Should be set as a
397     * string.
398     * Can be used with {@link #TYPE_ELECTRONIC}.
399     */
400    public static final String ARG_USERNAME = "android.arg.username";
401
402    /**
403     * Argument used to specify the password part of a URI. Should be set as a
404     * string.
405     * Can be used with {@link #TYPE_ELECTRONIC}.
406     */
407    public static final String ARG_PASSWORD = "android.arg.password";
408
409    /**
410     * Argument used to specify the domain part of a URI. For example
411     * "source.android.com".
412     * Can be used with {@link #TYPE_ELECTRONIC}.
413     */
414    public static final String ARG_DOMAIN = "android.arg.domain";
415
416    /**
417     * Argument used to specify the port number of a URI. Should be specified as
418     * an integer.
419     * Can be used with {@link #TYPE_ELECTRONIC}.
420     */
421    public static final String ARG_PORT = "android.arg.port";
422
423    /**
424     * Argument used to specify the path part of a URI. For example
425     * "source/index.html".
426     * Can be used with {@link #TYPE_ELECTRONIC}.
427     */
428    public static final String ARG_PATH = "android.arg.path";
429
430    /**
431     * Argument used to specify the query string of a URI. For example
432     * "arg=value&argtwo=value".
433     * Can be used with {@link #TYPE_ELECTRONIC}.
434     */
435    public static final String ARG_QUERY_STRING = "android.arg.query_string";
436
437    /**
438     * Argument used to specify the fragment id of a URI. Should be specified as
439     * a string.
440     * Can be used with {@link #TYPE_ELECTRONIC}.
441     */
442    public static final String ARG_FRAGMENT_ID = "android.arg.fragment_id";
443
444    /**
445     * Argument used to specify the currency. Should be a ISO4217 currency code,
446     * e.g. "USD".
447     * Can be used with {@link #TYPE_MONEY}.
448     */
449    public static final String ARG_CURRENCY = "android.arg.money";
450
451    /**
452     * Argument used to specify a string of digits.
453     * Can be used with {@link #TYPE_DIGITS}.
454     */
455    public static final String ARG_DIGITS = "android.arg.digits";
456
457    /**
458     * Argument used to specify a string where the characters are read verbatim,
459     * except whitespace.
460     * Can be used with {@link #TYPE_VERBATIM}.
461     */
462    public static final String ARG_VERBATIM = "android.arg.verbatim";
463
464    public TtsSpan(String type, PersistableBundle args) {
465        mType = type;
466        mArgs = args;
467    }
468
469    public TtsSpan(Parcel src) {
470        mType = src.readString();
471        mArgs = src.readPersistableBundle();
472    }
473
474    /**
475     * Returns the type.
476     * @return The type of this instance.
477     */
478    public String getType() {
479        return mType;
480    }
481
482    /**
483     * Returns a bundle of the arguments set.
484     * @return The bundle of the arguments set.
485     */
486    public PersistableBundle getArgs() {
487        return mArgs;
488    }
489
490    @Override
491    public int describeContents() {
492        return 0;
493    }
494
495    @Override
496    public void writeToParcel(Parcel dest, int flags) {
497        dest.writeString(mType);
498        dest.writePersistableBundle(mArgs);
499    }
500
501    @Override
502    public int getSpanTypeId() {
503        return TextUtils.TTS_SPAN;
504    }
505
506    /**
507     * A simple builder for TtsSpans.
508     * This builder can be used directly, but the more specific subclasses of
509     * this builder like {@link TtsSpan.TextBuilder} and
510     * {@link TtsSpan.CardinalBuilder} are likely more useful.
511     *
512     * This class uses generics so methods from this class can return instances of
513     * its child classes, resulting in a fluent API (CRTP pattern).
514     */
515    public static abstract class Builder<C extends Builder<C>> {
516        // Holds the type of this class.
517        private final String mType;
518
519        // Holds the arguments of this class. It only stores objects of type
520        // String, Integer and Long.
521        private PersistableBundle mArgs = new PersistableBundle();
522
523        public Builder(String type) {
524            mType = type;
525        }
526
527        /**
528         * Returns a TtsSpan built from the parameters set by the setter
529         * methods.
530         * @return A TtsSpan built with parameters of this builder.
531         */
532        public TtsSpan build() {
533            return new TtsSpan(mType, mArgs);
534        }
535
536        /**
537         * Sets an argument to a string value.
538         * @param arg The argument name.
539         * @param value The value the argument should be set to.
540         * @return This instance.
541         */
542        @SuppressWarnings("unchecked")
543        public C setStringArgument(String arg, String value) {
544            mArgs.putString(arg, value);
545            return (C) this;
546        }
547
548        /**
549         * Sets an argument to an int value.
550         * @param arg The argument name.
551         * @param value The value the argument should be set to.
552         */
553        @SuppressWarnings("unchecked")
554        public C setIntArgument(String arg, int value) {
555            mArgs.putInt(arg, value);
556            return (C) this;
557        }
558
559        /**
560         * Sets an argument to a long value.
561         * @param arg The argument name.
562         * @param value The value the argument should be set to.
563         */
564        @SuppressWarnings("unchecked")
565        public C setLongArgument(String arg, long value) {
566            mArgs.putLong(arg, value);
567            return (C) this;
568        }
569    }
570
571    /**
572     * A builder for TtsSpans, has setters for morphosyntactic features.
573     * This builder can be used directly, but the more specific subclasses of
574     * this builder like {@link TtsSpan.TextBuilder} and
575     * {@link TtsSpan.CardinalBuilder} are likely more useful.
576     */
577    public static class SemioticClassBuilder<C extends SemioticClassBuilder<C>>
578            extends Builder<C> {
579
580        public SemioticClassBuilder(String type) {
581            super(type);
582        }
583
584        /**
585         * Sets the gender information for this instance.
586         * @param gender Can any of {@link TtsSpan#GENDER_NEUTRAL},
587         *     {@link TtsSpan#GENDER_MALE} and {@link TtsSpan#GENDER_FEMALE}.
588         * @return This instance.
589         */
590        public C setGender(String gender) {
591            return setStringArgument(TtsSpan.ARG_GENDER, gender);
592        }
593
594        /**
595         * Sets the animacy information for this instance.
596         * @param animacy Can be any of {@link TtsSpan#ANIMACY_ANIMATE} and
597         *     {@link TtsSpan#ANIMACY_INANIMATE}.
598         * @return This instance.
599         */
600        public C setAnimacy(String animacy) {
601            return setStringArgument(TtsSpan.ARG_ANIMACY, animacy);
602        }
603
604        /**
605         * Sets the multiplicity information for this instance.
606         * @param multiplicity Can be any of
607         *     {@link TtsSpan#MULTIPLICITY_SINGLE},
608         *     {@link TtsSpan#MULTIPLICITY_DUAL} and
609         *     {@link TtsSpan#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 TtsSpan#CASE_NOMINATIVE},
619         *     {@link TtsSpan#CASE_ACCUSATIVE}, {@link TtsSpan#CASE_DATIVE},
620         *     {@link TtsSpan#CASE_ABLATIVE}, {@link TtsSpan#CASE_GENITIVE},
621         *     {@link TtsSpan#CASE_VOCATIVE}, {@link TtsSpan#CASE_LOCATIVE} and
622         *     {@link TtsSpan#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 TtsSpan #TYPE_TEXT}.
632     */
633    public static class TextBuilder extends SemioticClassBuilder<TextBuilder> {
634
635        /**
636         * Creates a TtsSpan of type {@link TtsSpan#TYPE_TEXT}.
637         */
638        public TextBuilder() {
639            super(TtsSpan.TYPE_TEXT);
640        }
641
642        /**
643         * Creates a TtsSpan of type {@link TtsSpan#TYPE_TEXT} and sets the
644         * {@link TtsSpan#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 TtsSpan#ARG_TEXT} argument, the text to be
655         * synthesized.
656         * @param text The string that will be synthesized.
657         * @return This instance.
658         */
659        public TextBuilder setText(String text) {
660            return setStringArgument(TtsSpan.ARG_TEXT, text);
661        }
662    }
663
664    /**
665     * A builder for TtsSpans of type {@link TtsSpan #TYPE_CARDINAL}.
666     */
667    public static class CardinalBuilder extends SemioticClassBuilder<CardinalBuilder> {
668
669        /**
670         * Creates a TtsSpan of type {@link TtsSpan#TYPE_CARDINAL}.
671         */
672        public CardinalBuilder() {
673            super(TtsSpan.TYPE_CARDINAL);
674        }
675
676        /**
677         * Creates a TtsSpan of type {@link TtsSpan#TYPE_CARDINAL} and sets the
678         * {@link TtsSpan#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 TtsSpan#TYPE_CARDINAL} and sets the
689         * {@link TtsSpan#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 TtsSpan#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 TtsSpan#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