func highlight_source(source: &String) -> StringFormats and syntax-highlights one Talk declaration as escaped HTML.
Highlight ranges come from the self-hosted Talk scanner. Trivia and any unscanned suffix are escaped directly, so malformed input cannot inject markup.
View Source
pub func highlight_source(source: &String) -> String {
let formatted = format_source_snippet(source: source)
let scanned = scan(source: formatted)
let output = StringBuilder()
let cursor = 0
let token_index = 0
let comment_index = 0
let previous = ""
loop token_index < scanned.tokens.count || comment_index < scanned.comments.count {
let token_start = if token_index < scanned.tokens.count { scanned.tokens[token_index].span.lower } else { formatted.byte_count + 1 }
let comment_start = if comment_index < scanned.comments.count { scanned.comments[comment_index].start } else { formatted.byte_count + 1 }
if comment_start < token_start {
let comment = scanned.comments[comment_index]
if cursor < comment.start { output.append(string: escaped_html(text: byte_slice(text: formatted, start: cursor, end: comment.start))) }
output.append(string: highlighted(text: byte_slice(text: formatted, start: comment.start, end: comment.end), class_name: "comment"))
cursor = comment.end
comment_index = comment_index + 1
continue
}
let token = scanned.tokens[token_index]
if cursor < token.span.lower { output.append(string: escaped_html(text: byte_slice(text: formatted, start: cursor, end: token.span.lower))) }
let spelling = byte_slice(text: formatted, start: token.span.lower, end: token.span.upper)
let next = if token_index + 1 < scanned.tokens.count { kind_name(kind: scanned.tokens[token_index + 1].kind) } else { "" }
output.append(string: highlighted(text: spelling, class_name: token_class(kind: token.kind, spelling: spelling, previous: previous, next: next)))
previous = kind_name(kind: token.kind)
cursor = token.span.upper
token_index = token_index + 1
}
if cursor < formatted.byte_count { output.append(string: escaped_html(text: byte_slice(text: formatted, start: cursor, end: formatted.byte_count))) }
output.finish()
}