mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Replace tabs with spaces in raw elements. (#2042)
This commit is contained in:
parent
aea20670d8
commit
ca1096de78
@ -9,6 +9,7 @@ use typst::diag::FileError;
|
||||
use typst::eval::Bytes;
|
||||
use typst::syntax::{self, LinkedNode};
|
||||
use typst::util::option_eq;
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
|
||||
use super::{
|
||||
FontFamily, FontList, Hyphenate, LinebreakElem, SmartQuoteElem, TextElem, TextSize,
|
||||
@ -218,6 +219,21 @@ pub struct RawElem {
|
||||
#[internal]
|
||||
#[parse(theme_data.map(Some))]
|
||||
pub theme_data: Option<Bytes>,
|
||||
|
||||
/// The size for a tab stop in spaces. A tab is replaced with enough spaces to
|
||||
/// align with the next multiple of the size.
|
||||
///
|
||||
/// ````example
|
||||
/// #set raw(tab-size: 8)
|
||||
/// ```tsv
|
||||
/// Year Month Day
|
||||
/// 2000 2 3
|
||||
/// 2001 2 1
|
||||
/// 2002 3 10
|
||||
/// ```
|
||||
/// ````
|
||||
#[default(2)]
|
||||
pub tab_size: usize,
|
||||
}
|
||||
|
||||
impl RawElem {
|
||||
@ -247,7 +263,12 @@ impl Synthesize for RawElem {
|
||||
impl Show for RawElem {
|
||||
#[tracing::instrument(name = "RawElem::show", skip_all)]
|
||||
fn show(&self, _: &mut Vt, styles: StyleChain) -> SourceResult<Content> {
|
||||
let text = self.text();
|
||||
let mut text = self.text();
|
||||
if text.contains('\t') {
|
||||
let tab_size = RawElem::tab_size_in(styles);
|
||||
text = align_tabs(&text, tab_size);
|
||||
}
|
||||
|
||||
let lang = self
|
||||
.lang(styles)
|
||||
.as_ref()
|
||||
@ -609,3 +630,33 @@ fn item(
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace tabs with spaces to align with multiples of `tab_size`.
|
||||
fn align_tabs(text: &str, tab_size: usize) -> EcoString {
|
||||
let replacement = " ".repeat(tab_size);
|
||||
let divisor = tab_size.max(1);
|
||||
let amount = text.chars().filter(|&c| c == '\t').count();
|
||||
|
||||
let mut res = EcoString::with_capacity(text.len() - amount + amount * tab_size);
|
||||
let mut column = 0;
|
||||
|
||||
for grapheme in text.graphemes(true) {
|
||||
match grapheme {
|
||||
"\t" => {
|
||||
let required = tab_size - column % divisor;
|
||||
res.push_str(&replacement[..required]);
|
||||
column += required;
|
||||
}
|
||||
"\n" => {
|
||||
res.push_str(grapheme);
|
||||
column = 0;
|
||||
}
|
||||
_ => {
|
||||
res.push_str(grapheme);
|
||||
column += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
|
BIN
tests/ref/text/raw-tabs.png
Normal file
BIN
tests/ref/text/raw-tabs.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
11
tests/typ/text/raw-tabs.typ
Normal file
11
tests/typ/text/raw-tabs.typ
Normal file
@ -0,0 +1,11 @@
|
||||
// Test tabs in raw code.
|
||||
|
||||
---
|
||||
#set raw(tab-size: 8)
|
||||
|
||||
```tsv
|
||||
Year Month Day
|
||||
2000 2 3
|
||||
2001 2 1
|
||||
2002 3 10
|
||||
```
|
Loading…
x
Reference in New Issue
Block a user