mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
18. Restore list indent behavior
This commit is contained in:
parent
9d9a1b1e33
commit
2c9728f53b
@ -69,9 +69,11 @@ impl<'s> Lexer<'s> {
|
|||||||
self.newline
|
self.newline
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The number of characters until the most recent newline.
|
/// The number of characters until the most recent newline from an index.
|
||||||
pub fn column(&self) -> usize {
|
pub fn column(&self, index: usize) -> usize {
|
||||||
self.s.before().chars().rev().take_while(|&c| !is_newline(c)).count()
|
let mut s = self.s; // Make a new temporary scanner (cheap).
|
||||||
|
s.jump(index);
|
||||||
|
s.before().chars().rev().take_while(|&c| !is_newline(c)).count()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1545,11 +1545,7 @@ struct Token {
|
|||||||
/// Information about a newline if present (currently only relevant in Markup).
|
/// Information about a newline if present (currently only relevant in Markup).
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
struct Newline {
|
struct Newline {
|
||||||
/// The column of our token in its line.
|
/// The column of the start of our token in its line.
|
||||||
///
|
|
||||||
/// Note that this is actually the column of the first non-whitespace
|
|
||||||
/// `SyntaxKind` in the line, so `\n /**/- list` has column 2 (not 6)
|
|
||||||
/// because the block comment is the first non-space kind.
|
|
||||||
column: Option<usize>,
|
column: Option<usize>,
|
||||||
/// Whether any of our newlines were paragraph breaks.
|
/// Whether any of our newlines were paragraph breaks.
|
||||||
parbreak: bool,
|
parbreak: bool,
|
||||||
@ -1684,10 +1680,6 @@ impl<'s> Parser<'s> {
|
|||||||
|
|
||||||
/// The number of characters until the most recent newline from the current
|
/// The number of characters until the most recent newline from the current
|
||||||
/// token, or 0 if it did not follow a newline.
|
/// token, or 0 if it did not follow a newline.
|
||||||
///
|
|
||||||
/// Note that this is actually the column of the first non-whitespace
|
|
||||||
/// `SyntaxKind` in the line, so `\n /**/- list` has column 2 (not 6)
|
|
||||||
/// because the block comment is the first non-space kind.
|
|
||||||
fn current_column(&self) -> usize {
|
fn current_column(&self) -> usize {
|
||||||
self.token.newline.and_then(|newline| newline.column).unwrap_or(0)
|
self.token.newline.and_then(|newline| newline.column).unwrap_or(0)
|
||||||
}
|
}
|
||||||
@ -1852,29 +1844,30 @@ impl<'s> Parser<'s> {
|
|||||||
let (mut kind, mut node) = lexer.next();
|
let (mut kind, mut node) = lexer.next();
|
||||||
let mut n_trivia = 0;
|
let mut n_trivia = 0;
|
||||||
let mut had_newline = false;
|
let mut had_newline = false;
|
||||||
let mut newline = Newline { column: None, parbreak: false };
|
let mut parbreak = false;
|
||||||
|
|
||||||
while kind.is_trivia() {
|
while kind.is_trivia() {
|
||||||
if lexer.newline() {
|
had_newline |= lexer.newline(); // Newlines are always trivia.
|
||||||
// Newlines are always trivia.
|
parbreak |= kind == SyntaxKind::Parbreak;
|
||||||
had_newline = true;
|
|
||||||
newline.parbreak |= kind == SyntaxKind::Parbreak;
|
|
||||||
if lexer.mode() == LexMode::Markup {
|
|
||||||
newline.column = Some(lexer.column());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
n_trivia += 1;
|
n_trivia += 1;
|
||||||
nodes.push(node);
|
nodes.push(node);
|
||||||
start = lexer.cursor();
|
start = lexer.cursor();
|
||||||
(kind, node) = lexer.next();
|
(kind, node) = lexer.next();
|
||||||
}
|
}
|
||||||
if had_newline && nl_mode.stop_at(newline, kind) {
|
|
||||||
// Insert a temporary `SyntaxKind::End` to halt the parser.
|
|
||||||
// The actual kind will be restored from `node` later.
|
|
||||||
kind = SyntaxKind::End;
|
|
||||||
}
|
|
||||||
|
|
||||||
let newline = had_newline.then_some(newline);
|
let newline = if had_newline {
|
||||||
|
let column = (lexer.mode() == LexMode::Markup).then(|| lexer.column(start));
|
||||||
|
let newline = Newline { column, parbreak };
|
||||||
|
if nl_mode.stop_at(newline, kind) {
|
||||||
|
// Insert a temporary `SyntaxKind::End` to halt the parser.
|
||||||
|
// The actual kind will be restored from `node` later.
|
||||||
|
kind = SyntaxKind::End;
|
||||||
|
}
|
||||||
|
Some(newline)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
Token { kind, node, n_trivia, newline, start, prev_end }
|
Token { kind, node, n_trivia, newline, start, prev_end }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,51 @@ _Shopping list_
|
|||||||
- C
|
- C
|
||||||
- D
|
- D
|
||||||
|
|
||||||
|
--- list-indent-trivia-nesting ---
|
||||||
|
// Test indent nesting behavior with odd trivia (comments and spaces).
|
||||||
|
|
||||||
|
#let indented = [
|
||||||
|
- a
|
||||||
|
/**/- b
|
||||||
|
/**/ - c
|
||||||
|
/*spanning
|
||||||
|
multiple
|
||||||
|
lines */ - d
|
||||||
|
- e
|
||||||
|
/**/ - f
|
||||||
|
/**/ - g
|
||||||
|
]
|
||||||
|
// Current behavior is that list columns are based on the first non-whitespace
|
||||||
|
// element in their line, so the block comments here determine the column the
|
||||||
|
// list starts at
|
||||||
|
|
||||||
|
#let item = list.item
|
||||||
|
#let manual = {
|
||||||
|
[ ]
|
||||||
|
item({
|
||||||
|
[a]
|
||||||
|
[ ]
|
||||||
|
item[b]
|
||||||
|
[ ]; [ ]
|
||||||
|
item({
|
||||||
|
[c]
|
||||||
|
[ ]; [ ]
|
||||||
|
item[d]
|
||||||
|
})
|
||||||
|
[ ]
|
||||||
|
item({
|
||||||
|
[e]
|
||||||
|
[ ]; [ ]
|
||||||
|
item[f]
|
||||||
|
[ ]; [ ]
|
||||||
|
item[g]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
[ ]
|
||||||
|
}
|
||||||
|
|
||||||
|
#test(indented, manual)
|
||||||
|
|
||||||
--- list-tabs ---
|
--- list-tabs ---
|
||||||
// This works because tabs are used consistently.
|
// This works because tabs are used consistently.
|
||||||
- A with 1 tab
|
- A with 1 tab
|
||||||
|
Loading…
x
Reference in New Issue
Block a user