mirror of
https://github.com/storytold/deckcraft.git
synced 2026-11-03 08:50:47 -06:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8114eb8218 |
@@ -390,6 +390,7 @@ pub fn pdf_options(p: &Value, count: usize) -> Result<deckcraft_pdf::PdfOptions>
|
||||
pub fn parse_slide_range(text: &str, count: usize) -> Result<Vec<usize>> {
|
||||
let invalid = || bad("file.export", format!("“{text}” isn't a valid slide range: use numbers and ranges such as 1-3, 5"));
|
||||
let mut out: Vec<usize> = vec![];
|
||||
let mut seen: std::collections::HashSet<usize> = std::collections::HashSet::new();
|
||||
for part in text.split([',', ';']).map(str::trim).filter(|p| !p.is_empty()) {
|
||||
let (a, b) = match part.split_once('-') {
|
||||
Some((a, b)) => (a.trim(), b.trim()),
|
||||
@@ -405,7 +406,7 @@ pub fn parse_slide_range(text: &str, count: usize) -> Result<Vec<usize>> {
|
||||
return Err(bad("file.export", format!("the presentation has {count} slides; “{part}” is outside them")));
|
||||
}
|
||||
for i in lo - 1..hi {
|
||||
if !out.contains(&i) {
|
||||
if seen.insert(i) {
|
||||
out.push(i);
|
||||
}
|
||||
}
|
||||
@@ -769,6 +770,16 @@ mod tests {
|
||||
|
||||
use super::{parse_slide_range, write_file};
|
||||
|
||||
#[test]
|
||||
fn broad_and_repeated_slide_ranges_expand_once() {
|
||||
// 200 copies of a 100,000-slide range: each index once, in order, without a scan per index.
|
||||
let text = vec!["1-100000"; 200].join(",");
|
||||
let v = parse_slide_range(&text, 100_000).unwrap();
|
||||
assert_eq!(v.len(), 100_000);
|
||||
assert!(v.windows(2).all(|w| w[0] < w[1]));
|
||||
assert_eq!(parse_slide_range("3, 1-3, 2", 3).unwrap(), vec![2, 0, 1]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slide_range_rejects_plus_sign() {
|
||||
assert!(parse_slide_range("+2", 3).is_err());
|
||||
|
||||
@@ -367,7 +367,7 @@ fn spelling(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
}
|
||||
out.push(v);
|
||||
}
|
||||
let rep: Vec<usize> = crate::spell::repeated(para, &default).iter().map(|w| w.start).collect();
|
||||
let rep: std::collections::HashSet<usize> = crate::spell::repeated(para, &default).iter().map(|w| w.start).collect();
|
||||
for w in crate::spell::paragraph_words(para, &default) {
|
||||
if ignore.contains(&w.text.to_lowercase()) || rep.contains(&w.start) {
|
||||
continue;
|
||||
|
||||
@@ -405,8 +405,9 @@ fn select_slides(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
};
|
||||
s.select(|doc, sel| {
|
||||
if add {
|
||||
let mut have: std::collections::HashSet<_> = sel.slides.iter().copied().collect();
|
||||
for i in &ids {
|
||||
if !sel.slides.contains(i) {
|
||||
if have.insert(*i) {
|
||||
sel.slides.push(*i);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user