Home | History | Annotate | Download | only in style
      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 
    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