     ret = ''
 
     for i in [startIndex...endIndex]
-      character = str[i]
-        .replace('&', '&amp;')
-        .replace('"', '&quot;')
-        .replace("'", '&#39;')
-        .replace('<', '&lt;')
-        .replace('>', '&gt;')
+      character = switch str[i]
+        when '&' then '&amp;'
+        when '"' then '&quot;'
+        when "'" then '&#39;'
+        when '<' then '&lt;'
+        when '>' then '&gt;'
+        else str[i]
+
       ret += "<span class='character'>#{character}</span>"
 
     ret
-

      leadingHtml = ''
      trailingHtml = ''

      if hasLeadingWhitespace and match = /^[ ]+/.exec(html)
        classes = []
        classes.push('indent-guide') if hasIndentGuide
        classes.push('invisible-character') if invisibles.space
        classes.push('leading-whitespace')
        classes = classes.join(' ')

        match[0] = match[0].replace(/./g, invisibles.space) if invisibles.space
        leadingHtml = "<span class='#{classes}'>#{@wrapCharacters(match[0])}</span>"

        startIndex = match[0].length

      if hasTrailingWhitespace and match = /[ ]+$/.exec(html)
        classes = []
        classes.push('indent-guide') if hasIndentGuide and not hasLeadingWhitespace
        classes.push('invisible-character') if invisibles.space
        classes.push('trailing-whitespace')
        classes = classes.join(' ')

        match[0] = match[0].replace(/./g, invisibles.space) if invisibles.space
        trailingHtml = "<span class='#{classes}'>#{@wrapCharacters(match[0])}</span>"

    html = @value

    if @isHardTab
      classes = 'hard-tab'
      classes += ' indent-guide' if hasIndentGuide
      classes += ' invisible-character' if invisibles.tab
      html = html.replace /^./, (match) =>
        match = invisibles.tab ? match
        "<span class='#{classes}'>#{@wrapCharacters(match)}</span>"
