vertically aligned code comments

This commit is contained in:
りき萌 2025-08-30 13:13:29 +02:00
parent ee0a95974b
commit 408b984266
6 changed files with 83 additions and 12 deletions

View file

@ -15,6 +15,8 @@ use std::{collections::HashMap, fmt::Write};
use serde::{Deserialize, Serialize};
use crate::html::highlight::tokenize::Token;
use self::compiled::CompiledSyntax;
use super::EscapeHtml;
@ -82,13 +84,59 @@ pub struct Keyword {
pub only_replaces: Option<String>,
}
pub fn highlight(out: &mut String, syntax: &CompiledSyntax, code: &str) {
let tokens = syntax.tokenize(code);
fn write_tokens(
out: &mut String,
syntax: &CompiledSyntax,
code: &str,
tokens: impl Iterator<Item = Token>,
) {
for token in tokens {
let str = &code[token.range.clone()];
out.push_str("<span class=\"");
_ = write!(out, "{}", EscapeHtml(&syntax.token_names[token.id]));
out.push_str("\">");
_ = write!(out, "{}", EscapeHtml(&code[token.range]));
_ = write!(out, "{}", EscapeHtml(str));
out.push_str("</span>");
}
}
pub fn highlight(out: &mut String, syntax: &CompiledSyntax, code: &str) {
let tokens = syntax.tokenize(code);
let mut line = vec![];
let mut in_columns = false;
for token in tokens {
let str = &code[token.range.clone()];
line.push(token);
if str.ends_with('\n') {
let line_comment = if line.last().is_some_and(|token| {
Some(token.id) == syntax.comment_token_id
&& code[token.range.clone()].ends_with('\n')
}) {
line.pop()
} else {
None
};
if let Some(line_comment) = line_comment {
if !in_columns {
out.push_str("<th-comment-columns>");
in_columns = true;
}
out.push_str("<span>");
write_tokens(out, syntax, code, line.drain(..));
out.push_str("</span>");
write_tokens(out, syntax, code, [line_comment].into_iter());
} else {
if in_columns {
out.push_str("</th-comment-columns>");
in_columns = false;
}
write_tokens(out, syntax, code, line.drain(..));
}
}
}
}