highlight_source

func highlight_source(source: &String) -> String

Formats 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()
}