now we can parse an entire presentation to a list of slides

This commit is contained in:
Chris Cochrun 2024-12-06 11:15:41 -06:00
parent 6779b0c77c
commit 87a26642fa
5 changed files with 193 additions and 19 deletions

View file

@ -9,6 +9,8 @@ use std::{
};
use tracing::error;
use super::songs::Song;
#[derive(
Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize,
)]
@ -174,6 +176,7 @@ pub struct Slide {
font: String,
font_size: i32,
text_alignment: TextAlignment,
audio: Option<PathBuf>,
video_loop: bool,
video_start_time: f32,
video_end_time: f32,
@ -199,10 +202,42 @@ impl Slide {
pub fn video_loop(&self) -> bool {
self.video_loop
}
pub fn song_slides(song: &Song) -> Result<Vec<Self>> {
let lyrics = song.get_lyrics()?;
let slides: Vec<Slide> = lyrics
.iter()
.map(|l| {
let song = song.clone();
SlideBuilder::new()
.background(song.background.unwrap_or_default())
.font(song.font.unwrap_or_default())
.font_size(song.font_size.unwrap_or_default())
.text_alignment(
song.text_alignment.unwrap_or_default(),
)
.audio(song.audio.unwrap_or_default())
.video_loop(true)
.video_start_time(0.0)
.video_end_time(0.0)
.text(l)
.build()
.unwrap_or_default()
})
.collect();
Ok(slides)
}
}
impl From<Value> for Slide {
fn from(value: Value) -> Self {
Self::from(&value)
}
}
impl From<&Value> for Slide {
fn from(value: &Value) -> Self {
match value {
Value::List(list) => lisp_to_slide(list),
_ => Slide::default(),
@ -210,7 +245,7 @@ impl From<Value> for Slide {
}
}
fn lisp_to_slide(lisp: Vec<Value>) -> Slide {
fn lisp_to_slide(lisp: &Vec<Value>) -> Slide {
const DEFAULT_BACKGROUND_LOCATION: usize = 1;
const DEFAULT_TEXT_LOCATION: usize = 0;
@ -327,11 +362,9 @@ pub fn lisp_to_background(lisp: &Value) -> Background {
home.push_str("/");
let s = s.replace("./", &home);
dbg!(&s);
match Background::try_from(s.as_str()) {
Ok(background) => background,
Err(e) => {
dbg!(&e);
error!(
"Couldn't load background: {e}"
);
@ -368,6 +401,7 @@ pub struct SlideBuilder {
text: Option<String>,
font: Option<String>,
font_size: Option<i32>,
audio: Option<PathBuf>,
text_alignment: Option<TextAlignment>,
video_loop: Option<bool>,
video_start_time: Option<f32>,
@ -401,6 +435,11 @@ impl SlideBuilder {
self
}
pub(crate) fn audio(mut self, audio: impl Into<PathBuf>) -> Self {
let _ = self.audio.insert(audio.into());
self
}
pub(crate) fn font(mut self, font: impl Into<String>) -> Self {
let _ = self.font.insert(font.into());
self
@ -471,6 +510,7 @@ impl SlideBuilder {
font,
font_size,
text_alignment,
audio: self.audio,
video_loop,
video_start_time,
video_end_time,

View file

@ -103,7 +103,7 @@ impl From<Value> for Song {
}
}
fn lisp_to_song(list: Vec<Value>) -> Song {
pub fn lisp_to_song(list: Vec<Value>) -> Song {
const DEFAULT_SONG_ID: i32 = 0;
const DEFAULT_SONG_LOCATION: usize = 0;
@ -273,7 +273,6 @@ fn lisp_to_song(list: Vec<Value>) -> Song {
};
let lyric = format!("{verse_title}{lyric}");
println!("lyric_final: {lyric}");
let lyric = lyric.replace(
"\\n", r#"
"#,
@ -592,8 +591,6 @@ You saved my soul"
let value = test_lisp_song();
let lisp_song = Song::from(value);
let test_song = test_song();
println!("test_song: {}", test_song.lyrics.clone().unwrap());
println!("lisp_song: {}", lisp_song.lyrics.clone().unwrap());
assert_eq!(test_song, lisp_song);
}
}

View file

@ -1,6 +1,7 @@
use crisp::types::{Symbol, Value};
use tracing::error;
use crate::Slide;
use crate::{core::songs::lisp_to_song, Slide};
pub fn parse_lisp(value: Value) -> Vec<Slide> {
match &value {
@ -10,7 +11,14 @@ pub fn parse_lisp(value: Value) -> Vec<Slide> {
vec![slide]
}
Value::Symbol(Symbol(s)) if s == "song" => {
vec![Slide::default()]
let song = lisp_to_song(vec.clone());
match Slide::song_slides(&song) {
Ok(s) => s,
Err(e) => {
error!("Couldn't load song: {e}");
vec![Slide::default()]
}
}
}
Value::Symbol(Symbol(s)) if s == "load" => {
vec![Slide::default()]
@ -23,7 +31,7 @@ pub fn parse_lisp(value: Value) -> Vec<Slide> {
#[cfg(test)]
mod test {
use std::fs::read_to_string;
use std::{fs::read_to_string, path::PathBuf};
use crate::{Background, SlideBuilder, TextAlignment};
@ -49,6 +57,31 @@ mod test {
}
}
#[test]
fn test_parsing_lisp_presentation() {
let lisp =
read_to_string("./test_presentation.lisp").expect("oops");
let lisp_value = crisp::reader::read(&lisp);
let test_vec =
vec![test_slide(), test_second_slide(), song_slide()];
match lisp_value {
Value::List(value) => {
let mut slide_vec = vec![];
for value in value {
let mut vec = parse_lisp(value);
slide_vec.append(&mut vec);
}
let first_lisp_slide = &slide_vec[0];
let second_lisp_slide = &slide_vec[1];
let third_lisp_slide = &slide_vec[2];
assert_eq!(first_lisp_slide, &test_vec[0]);
assert_eq!(second_lisp_slide, &test_vec[1]);
assert_eq!(third_lisp_slide, &test_vec[2]);
}
_ => panic!("this should be a lisp"),
}
}
fn test_slide() -> Slide {
SlideBuilder::new()
.text("This is frodo")
@ -81,4 +114,22 @@ mod test {
.build()
.unwrap()
}
fn song_slide() -> Slide {
SlideBuilder::new()
.text("Death Was Arrested\nNorth Point Worship")
.background(
Background::try_from("~/nc/tfc/openlp/CMG - Bright Mountains 01.jpg")
.unwrap(),
)
.font("Quicksand Bold")
.font_size(60)
.text_alignment(TextAlignment::MiddleCenter)
.audio(PathBuf::from("file:///home/chris/music/North Point InsideOut/Nothing Ordinary, Pt. 1 (Live)/05 Death Was Arrested (feat. Seth Condrey).mp3"))
.video_loop(true)
.video_start_time(0.0)
.video_end_time(0.0)
.build()
.unwrap()
}
}