summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeedehai <18319900+Leedehai@users.noreply.github.com>2024-04-02 05:07:00 -0400
committerGitHub <noreply@github.com>2024-04-02 09:07:00 +0000
commitc225adb22bb6a445f1cf7f0261e9a937ce397988 (patch)
tree6bd75557a78aed5bb2e4022a93273e67936f9cf0
parentf461b2059d6733621630f07bc1c9ee039408c9be (diff)
Fix tab rendering for raw block with lang "typ(c)" (#3847)
-rw-r--r--crates/typst/src/text/raw.rs42
-rw-r--r--tests/ref/bugs/3841-tabs-in-raw-typ-code.pngbin0 -> 13011 bytes
-rw-r--r--tests/typ/bugs/3841-tabs-in-raw-typ-code.typ20
3 files changed, 45 insertions, 17 deletions
diff --git a/crates/typst/src/text/raw.rs b/crates/typst/src/text/raw.rs
index 424adb72..2d590d2a 100644
--- a/crates/typst/src/text/raw.rs
+++ b/crates/typst/src/text/raw.rs
@@ -300,22 +300,7 @@ impl Packed<RawElem> {
#[comemo::memoize]
fn highlight(&self, styles: StyleChain) -> Vec<Packed<RawLine>> {
let elem = self.as_ref();
-
- let text = elem.text();
- let lines = match text {
- RawContent::Lines(lines) if !lines.iter().any(|(s, _)| s.contains('\t')) => {
- lines.clone()
- }
- _ => {
- let mut text = text.get();
- if text.contains('\t') {
- let tab_size = RawElem::tab_size_in(styles);
- text = align_tabs(&text, tab_size);
- }
- let lines = split_newlines(&text);
- lines.into_iter().map(|line| (line.into(), self.span())).collect()
- }
- };
+ let lines = preprocess(elem.text(), styles, self.span());
let count = lines.len() as i64;
let lang = elem
@@ -339,7 +324,8 @@ impl Packed<RawElem> {
let mut seq = vec![];
if matches!(lang.as_deref(), Some("typ" | "typst" | "typc")) {
- let text = text.get();
+ let text =
+ lines.iter().map(|(s, _)| s.clone()).collect::<Vec<_>>().join("\n");
let root = match lang.as_deref() {
Some("typc") => syntax::parse_code(&text),
_ => syntax::parse(&text),
@@ -683,6 +669,28 @@ impl<'a> ThemedHighlighter<'a> {
}
}
+fn preprocess(
+ text: &RawContent,
+ styles: StyleChain,
+ span: Span,
+) -> EcoVec<(EcoString, Span)> {
+ if let RawContent::Lines(lines) = text {
+ if lines.iter().all(|(s, _)| !s.contains('\t')) {
+ return lines.clone();
+ }
+ }
+
+ let mut text = text.get();
+ if text.contains('\t') {
+ let tab_size = RawElem::tab_size_in(styles);
+ text = align_tabs(&text, tab_size);
+ }
+ split_newlines(&text)
+ .into_iter()
+ .map(|line| (line.into(), span))
+ .collect()
+}
+
/// Style a piece of text with a syntect style.
fn styled(
piece: &str,
diff --git a/tests/ref/bugs/3841-tabs-in-raw-typ-code.png b/tests/ref/bugs/3841-tabs-in-raw-typ-code.png
new file mode 100644
index 00000000..37dab136
--- /dev/null
+++ b/tests/ref/bugs/3841-tabs-in-raw-typ-code.png
Binary files differ
diff --git a/tests/typ/bugs/3841-tabs-in-raw-typ-code.typ b/tests/typ/bugs/3841-tabs-in-raw-typ-code.typ
new file mode 100644
index 00000000..db04fe3c
--- /dev/null
+++ b/tests/typ/bugs/3841-tabs-in-raw-typ-code.typ
@@ -0,0 +1,20 @@
+// Issue 3841 Tab chars are not rendered in raw blocks with lang: "typ(c)"
+// https://github.com/typst/typst/issues/3841
+
+#raw("#if true {\n\tf()\t// typ\n}", lang: "typ")
+
+#raw("if true {\n\tf()\t// typc\n}", lang: "typc")
+
+```typ
+#if true {
+ // tabs around f()
+ f() // typ
+}
+```
+
+```typc
+if true {
+ // tabs around f()
+ f() // typc
+}
+```