Handle invisible character rendering when building HTML for lines.

Not during creation of tokens.
This commit is contained in:
Corey Johnson & Nathan Sobo
2012-10-18 11:43:17 -07:00
parent dd5a10e82e
commit b33bbbfc0d
6 changed files with 57 additions and 97 deletions

View File

@@ -876,9 +876,18 @@ class Editor extends View
if screenLine.text == ''
line.push(" ") unless @activeEditSession.showInvisibles
else
firstNonWhitespacePosition = screenLine.text.search(/\S/)
firstTrailingWhitespacePosition = screenLine.text.search(/\s*$/)
position = 0
for token in screenLine.tokens
updateScopeStack(token.scopes)
line.push(token.escapeValue(@activeEditSession.showInvisibles))
line.push(token.getValueAsHtml(
showInvisibles: @activeEditSession.showInvisibles
hasLeadingWhitespace: position < firstNonWhitespacePosition
hasTrailingWhitespace: position + token.value.length > firstTrailingWhitespacePosition
))
position += token.value.length
line.push("<span class='invisible'>¬</span>") if @activeEditSession.showInvisibles
line.push('</pre>')

View File

@@ -5,6 +5,7 @@ class Token
value: null
scopes: null
isAtomic: null
isTab: null
constructor: ({@value, @scopes, @isAtomic, @bufferDelta, @fold, @isTab}) ->
@screenDelta = @value.length
@@ -21,29 +22,41 @@ class Token
value2 = @value.substring(splitIndex)
[new Token(value: value1, scopes: @scopes), new Token(value: value2, scopes: @scopes)]
breakOutWhitespaceCharacters: (tabLength, showInvisibles) ->
return [this] unless /\t| /.test(@value)
for substring in @value.match(/([^\t ]+|(\t| +))/g)
scopesForInvisibles = if showInvisibles then @scopes.concat("invisible") else @scopes
breakOutTabCharacters: (tabLength, showInvisibles) ->
return [this] unless /\t/.test(@value)
for substring in @value.match(/[^\t]+|\t/g)
if substring == "\t"
value = new Array(tabLength + 1).join(" ")
value = "" + value[1..] if showInvisibles
new Token(value: value, scopes: scopesForInvisibles, bufferDelta: 1, isAtomic: true)
else if /^ +$/.test(substring)
value = if showInvisibles then substring.replace(/[ ]/g, "") else substring
new Token(value: value, scopes: scopesForInvisibles)
@buildTabToken(tabLength)
else
new Token(value: substring, scopes: @scopes)
buildTabToken: (tabLength) ->
tabText = new Array(tabLength + 1).join(" ")
new Token(
value: new Array(tabLength + 1).join(" ")
scopes: @scopes
bufferDelta: 1
isAtomic: true
isTab: true
)
escapeValue: (showInvisibles)->
@value
getValueAsHtml: ({showInvisibles, hasLeadingWhitespace, hasTrailingWhitespace})->
html = @value
.replace(/&/g, '&amp;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
if showInvisibles
if @isTab
html = html.replace(/^./, "<span class='invisible'>▸</span>")
else
if hasLeadingWhitespace
html = html.replace /^[ ]+/, (match) ->
"<span class='invisible'>#{match.replace(/./g, '')}</span>"
if hasTrailingWhitespace
html = html.replace /[ ]+$/, (match) ->
"<span class='invisible'>#{match.replace(/./g, '')}</span>"
html

View File

@@ -67,7 +67,7 @@ class TokenizedBuffer
tokenObjects = []
for tokenProperties in tokens
token = new Token(tokenProperties)
tokenObjects.push(token.breakOutWhitespaceCharacters(@tabLength, @showInvisibles)...)
tokenObjects.push(token.breakOutTabCharacters(@tabLength, @showInvisibles)...)
text = _.pluck(tokenObjects, 'value').join('')
new ScreenLine(tokenObjects, text, [1, 0], [1, 0], { stack })