# File lib/maruku/input/parse_span_better.rb, line 54
        def read_span(src, escaped, exit_on_chars, exit_on_strings=nil)
                con = SpanContext.new
                c = d = nil
                while true
                        c = src.cur_char

                        # This is only an optimization which cuts 50% of the time used.
                        # (but you can't use a-zA-z in exit_on_chars)
                        if c && ((c>=?a && c<=?z) || ((c>=?A && c<=?Z)))
                                con.cur_string << src.shift_char
                                next
                        end

                        break if exit_on_chars && exit_on_chars.include?(c)
                        break if exit_on_strings && exit_on_strings.any? {|x| src.cur_chars_are x}
                        
                        # check if there are extensions
                        if check_span_extensions(src, con)
                                next
                        end
                        
                        case c = src.cur_char        
                        when ?\ # it's space (32)
                                if src.cur_chars_are "  \n"
                                        src.ignore_chars(3)
                                        con.push_element  md_br()
                                        next
                                else
                                        src.ignore_char
                                        con.push_space 
                                end
                        when ?\n, ?\t 
                                src.ignore_char
                                con.push_space 
                        when ?`
                                read_inline_code(src,con)
                        when ?<
                                # It could be:
                                # 1) HTML "<div ..."
                                # 2) HTML "<!-- ..."
                                # 3) url "<http:// ", "<ftp:// ..."
                                # 4) email "<andrea@... ", "<mailto:andrea@..."
                                # 5) on itself! "a < b      "
                                # 6) Start of <<guillemettes>>
                                
                                case d = src.next_char
                                        when ?<;  # guillemettes
                                                src.ignore_chars(2)
                                                con.push_char ?<
                                                con.push_char ?<
                                        when ?!; 
                                                if src.cur_chars_are '<!--'
                                                        read_inline_html(src, con)
                                                else 
                                                        con.push_char src.shift_char
                                                end
                                        when ?? 
                                                read_xml_instr_span(src, con) 
                                        when ?\ , ?\t 
                                                con.push_char src.shift_char
                                        else
                                                if src.next_matches(/<mailto:/) or
                                                   src.next_matches(/<[\w\.]+\@/)
                                                        read_email_el(src, con)
                                                elsif src.next_matches(/<\w+:/)
                                                        read_url_el(src, con)
                                                elsif src.next_matches(/<\w/)
                                                        #puts "This is HTML: #{src.cur_chars(20)}"
                                                        read_inline_html(src, con)
                                                else 
                                                        #puts "This is NOT HTML: #{src.cur_chars(20)}"
                                                        con.push_char src.shift_char
                                                end
                                end
                        when ?\\
                                d = src.next_char
                                if d == ?'
                                        src.ignore_chars(2)
                                        con.push_element md_entity('apos')
                                elsif d == ?"
                                        src.ignore_chars(2)
                                        con.push_element md_entity('quot')
                                elsif escaped.include? d
                                        src.ignore_chars(2)
                                        con.push_char d
                                else
                                        con.push_char src.shift_char
                                end
                        when ?[
                                if markdown_extra? && src.next_char == ?^
                                        read_footnote_ref(src,con)
                                else
                                        read_link(src, con)
                                end
                        when ?!
                                if src.next_char == ?[
                                        read_image(src, con)
                                else
                                        con.push_char src.shift_char
                                end
                        when ?&
                                # named references
                                if m = src.read_regexp(/\&([\w\d]+);/)
                                        con.push_element md_entity(m[1])
                                # numeric
                                elsif m = src.read_regexp(/\&\#(x)?([\w\d]+);/)
                                        num = m[1]  ? m[2].hex : m[2].to_i
                                        con.push_element md_entity(num)
                                else
                                        con.push_char src.shift_char
                                end
                        when ?*
                                if not src.next_char
                                        maruku_error "Opening * as last char.", src, con
                                        maruku_recover "Threating as literal"
                                        con.push_char src.shift_char
                                else
                                        follows = src.cur_chars(4)
                                        if follows =~ /^\*\*\*[^\s\*]/
                                                con.push_element read_emstrong(src,'***')
                                        elsif follows  =~ /^\*\*[^\s\*]/
                                                con.push_element read_strong(src,'**')
                                        elsif follows =~ /^\*[^\s\*]/
                                                con.push_element read_em(src,'*')
                                        else # * is just a normal char
                                                con.push_char src.shift_char
                                        end
                                end
                        when ?_
                                if not src.next_char
                                        maruku_error "Opening _ as last char", src, con
                                        maruku_recover "Threating as literal", src, con
                                        con.push_char src.shift_char
                                else
                                        # we don't want "mod_ruby" to start an emphasis
                                        # so we start one only if
                                        # 1) there's nothing else in the span (first char)
                                        # or 2) the last char was a space
                                        # or 3) the current string is empty
                                        #if con.elements.empty? ||
                                        if  (con.cur_string =~ /\s\Z/) || (con.cur_string.size == 0)
                                                # also, we check the next characters
                                                follows = src.cur_chars(4)
                                                if  follows =~ /^\_\_\_[^\s\_]/
                                                        con.push_element read_emstrong(src,'___')
                                                elsif follows  =~ /^\_\_[^\s\_]/
                                                        con.push_element read_strong(src,'__')
                                                elsif follows =~ /^\_[^\s\_]/
                                                        con.push_element read_em(src,'_')
                                                else # _ is just a normal char
                                                        con.push_char src.shift_char
                                                end
                                        else
                                                # _ is just a normal char
                                                        con.push_char src.shift_char
                                        end
                                end
                        when ?{ # extension
                                if [?#, ?., ?:].include? src.next_char
                                        src.ignore_char # {
                                        interpret_extension(src, con, [?}])
                                        src.ignore_char # }
                                else
                                        con.push_char src.shift_char
                                end
                        when nil
                                maruku_error( ("Unclosed span (waiting for %s"+
                                 "#{exit_on_strings.inspect})") % [
                                                exit_on_chars ? "#{exit_on_chars.inspect} or" : ""],
                                                src,con)
                                break
                        else # normal text
                                con.push_char src.shift_char
                        end # end case
                end # end while true
                con.push_string_if_present 

                # Assign IAL to elements
                merge_ial(con.elements, src, con)
                
                
                # Remove leading space
                if (s = con.elements.first).kind_of? String
                        if s[0] == ?\ then con.elements[0] = s[1, s.size-1] end
                        con.elements.shift if s.size == 0 
                end
                
                # Remove final spaces
                if (s = con.elements.last).kind_of? String
                        s.chop! if s[-1] == ?\ 
                        con.elements.pop if s.size == 0 
                end
                
                educated = educate(con.elements)

                educated
        end