def tokenize_and_align_positions(origin_text, start_position, end_position, tokenizer):
    """Tokenize the text and align the origin positions to the corresponding position.

    Parameters
    ----------
    origin_text : list
        list of tokens to be tokenized.
    start_position : int
        Start position in the origin_text
    end_position : int
        End position in the origin_text
    tokenizer : callable function, e.g., BERTTokenizer.

    Returns
    -------
    int: Aligned start position
    int: Aligned end position
    list: tokenized text
    list: map from the origin index to the tokenized sequence index
    list: map from tokenized sequence index to the origin index

    Examples
    --------
    >>> from gluonnlp.vocab import BERTVocab
    >>> from gluonnlp.data import count_tokens, BERTTokenizer
    >>> origin_text = ['is', 'this', 'jacksonville', '?']
    >>> vocab_tokens = ['is', 'this', 'jack', '##son', '##ville', '?']
    >>> bert_vocab = BERTVocab(count_tokens(vocab_tokens))
    >>> tokenizer = BERTTokenizer(vocab=bert_vocab)
    >>> out = tokenize_and_align_positions(origin_text, 0, 2, tokenizer)
    >>> out[0] # start_position
    0
    >>> out[1] # end_position
    4
    >>> out[2] # tokenized_text
    ['is', 'this', 'jack', '##son', '##ville', '?']
    >>> out[3] # orig_to_tok_index
    [0, 1, 2, 5]
    >>> out[4] # tok_to_orig_index
    [0, 1, 2, 2, 2, 3]
    """
    orig_to_tok_index = []
    tok_to_orig_index = []
    tokenized_text = []
    for (i, token) in enumerate(origin_text):
        orig_to_tok_index.append(len(tokenized_text))
        sub_tokens = tokenizer(token)
        tokenized_text += sub_tokens
        tok_to_orig_index += [i] * len(sub_tokens)

    start_position = orig_to_tok_index[start_position]
    end_position = orig_to_tok_index[end_position + 1] - 1 if end_position < len(origin_text) - 1  \
        else len(tokenized_text) - 1
    return start_position, end_position, tokenized_text, orig_to_tok_index, tok_to_orig_index