language support

This commit is contained in:
Dominic 2024-05-17 21:29:22 +02:00
parent f5ec5db460
commit cd705c1153
Signed by: msrd0
GPG key ID: AAF7C8430CA3345D
4 changed files with 140 additions and 36 deletions

View file

@ -1,11 +1,125 @@
//! A module for writing intros and outros //! A module for writing intros and outros
use crate::{time::format_date_long, ProjectLecture, Resolution}; use crate::{time::Date, ProjectLecture, Resolution};
use anyhow::anyhow;
use std::{
fmt::{self, Debug, Display, Formatter},
str::FromStr
};
use svgwriter::{ use svgwriter::{
tags::{Group, Rect, TagWithPresentationAttributes, Text}, tags::{Group, Rect, TagWithPresentationAttributes, Text},
Graphic Graphic
}; };
#[derive(Clone)]
pub struct Language<'a> {
lang: &'a str,
format_date_long: fn(Date) -> String,
// intro
lecture_from: &'a str,
video_created_by_us: &'a str,
// outro
video_created_by: &'a str,
our_website: &'a str,
download_videos: &'a str,
questions_feedback: &'a str
}
pub const GERMAN: Language<'static> = Language {
lang: "de",
// Format a date in DD. MMMM YYYY format.
format_date_long: |d: Date| {
let month = match d.month {
1 => "Januar",
2 => "Februar",
3 => "März",
4 => "April",
5 => "Mai",
6 => "Juni",
7 => "Juli",
8 => "August",
9 => "September",
10 => "Oktober",
11 => "November",
12 => "Dezember",
_ => unreachable!()
};
format!("{:02}. {month} {:04}", d.day, d.year)
},
lecture_from: "Vorlesung vom",
video_created_by_us: "Video erstellt von der Video AG, Fachschaft I/1",
video_created_by: "Video erstellt von der",
our_website: "Website der Fachschaft",
download_videos: "Videos herunterladen",
questions_feedback: "Fragen, Vorschläge und Feedback"
};
pub const BRITISH: Language<'static> = Language {
lang: "uk",
// Format a date in DDth MMMM YYYY format.
format_date_long: |d: Date| {
let month = match d.month {
1 => "January",
2 => "February",
3 => "March",
4 => "April",
5 => "May",
6 => "June",
7 => "July",
8 => "August",
9 => "September",
10 => "October",
11 => "November",
12 => "December",
_ => unreachable!()
};
let th = match d.day {
1 | 21 | 31 => "st",
2 | 22 => "nd",
3 | 23 => "rd",
_ => "th"
};
format!("{:02}{th} {month} {:04}", d.day, d.year)
},
lecture_from: "Lecture from",
video_created_by_us: "Video created by the Video AG, Fachschaft I/1",
video_created_by: "Video created by the",
our_website: "The Fachschaft's website",
download_videos: "Download videos",
questions_feedback: "Questions, Suggestions and Feedback"
};
impl FromStr for Language<'static> {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"de" => Ok(GERMAN),
"en" | "uk" => Ok(BRITISH),
lang => Err(anyhow!("Unknown language {lang:?}"))
}
}
}
impl Display for Language<'_> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.write_str(self.lang)
}
}
impl Debug for Language<'_> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("Language")
.field("lang", &self.lang)
.finish_non_exhaustive()
}
}
#[repr(u16)] #[repr(u16)]
enum FontSize { enum FontSize {
Huge = 72, Huge = 72,
@ -74,6 +188,7 @@ impl Iotro {
pub(crate) fn intro(res: Resolution, lecture: &ProjectLecture) -> Graphic { pub(crate) fn intro(res: Resolution, lecture: &ProjectLecture) -> Graphic {
use self::{FontSize::*, FontWeight::*}; use self::{FontSize::*, FontWeight::*};
let lang = &lecture.lang;
let mut intro = Iotro::new(res); let mut intro = Iotro::new(res);
intro.add_text(Huge, Bold, 110, &lecture.label); intro.add_text(Huge, Bold, 110, &lecture.label);
intro.add_text(Huge, SemiBold, 250, &lecture.docent); intro.add_text(Huge, SemiBold, 250, &lecture.docent);
@ -81,31 +196,30 @@ pub(crate) fn intro(res: Resolution, lecture: &ProjectLecture) -> Graphic {
Huge, Huge,
SemiBold, SemiBold,
460, 460,
format!("Vorlesung vom {}", format_date_long(lecture.date)) format!(
); "{} {}",
intro.add_text( lang.lecture_from,
Big, (lang.format_date_long)(lecture.date)
Normal, )
870,
"Video erstellt von der Video AG, Fachschaft I/1"
); );
intro.add_text(Big, Normal, 870, lang.video_created_by_us);
intro.add_text(Big, Normal, 930, "https://video.fsmpi.rwth-aachen.de"); intro.add_text(Big, Normal, 930, "https://video.fsmpi.rwth-aachen.de");
intro.add_text(Big, Normal, 990, "video@fsmpi.rwth-aachen.de"); intro.add_text(Big, Normal, 990, "video@fsmpi.rwth-aachen.de");
intro.finish() intro.finish()
} }
pub(crate) fn outro(res: Resolution) -> Graphic { pub(crate) fn outro(lang: &Language<'_>, res: Resolution) -> Graphic {
use self::{FontSize::*, FontWeight::*}; use self::{FontSize::*, FontWeight::*};
let mut outro = Iotro::new(res); let mut outro = Iotro::new(res);
outro.add_text(Large, SemiBold, 50, "Video erstellt von der"); outro.add_text(Large, SemiBold, 50, lang.video_created_by);
outro.add_text(Huge, Bold, 210, "Video AG, Fachschaft I/1"); outro.add_text(Huge, Bold, 210, "Video AG, Fachschaft I/1");
outro.add_text(Large, Normal, 360, "Website der Fachschaft:"); outro.add_text(Large, Normal, 360, format!("{}:", lang.our_website));
outro.add_text(Large, Normal, 430, "https://www.fsmpi.rwth-aachen.de"); outro.add_text(Large, Normal, 430, "https://www.fsmpi.rwth-aachen.de");
outro.add_text(Large, Normal, 570, "Videos herunterladen:"); outro.add_text(Large, Normal, 570, format!("{}:", lang.download_videos));
outro.add_text(Large, Normal, 640, "https://video.fsmpi.rwth-aachen.de"); outro.add_text(Large, Normal, 640, "https://video.fsmpi.rwth-aachen.de");
outro.add_text(Large, Normal, 780, "Fragen, Vorschläge und Feedback:"); outro.add_text(Large, Normal, 780, format!("{}:", lang.questions_feedback));
outro.add_text(Large, Normal, 850, "video@fsmpi.rwth-aachen.de"); outro.add_text(Large, Normal, 850, "video@fsmpi.rwth-aachen.de");
outro.finish() outro.finish()

View file

@ -12,6 +12,7 @@ use crate::{
}; };
use camino::Utf8PathBuf as PathBuf; use camino::Utf8PathBuf as PathBuf;
use clap::Parser; use clap::Parser;
use iotro::Language;
use rational::Rational; use rational::Rational;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_with::{serde_as, DisplayFromStr}; use serde_with::{serde_as, DisplayFromStr};
@ -44,6 +45,10 @@ struct Args {
#[clap(short, long, default_value = "Prof. E. Grädel")] #[clap(short, long, default_value = "Prof. E. Grädel")]
docent: String, docent: String,
/// The language of the lecture. Used for the intro and outro frame.
#[clap(short = 'L', long, default_value = "de")]
lang: Language<'static>,
/// The memory limit for external tools like ffmpeg. /// The memory limit for external tools like ffmpeg.
#[clap(short, long, default_value = "12G")] #[clap(short, long, default_value = "12G")]
mem_limit: String, mem_limit: String,
@ -145,7 +150,9 @@ struct ProjectLecture {
label: String, label: String,
docent: String, docent: String,
#[serde_as(as = "DisplayFromStr")] #[serde_as(as = "DisplayFromStr")]
date: Date date: Date,
#[serde_as(as = "DisplayFromStr")]
lang: Language<'static>
} }
#[serde_as] #[serde_as]
@ -271,7 +278,8 @@ fn main() {
course, course,
label: args.label, label: args.label,
docent: args.docent, docent: args.docent,
date date,
lang: args.lang
}, },
source: ProjectSource { source: ProjectSource {
files, files,

View file

@ -272,7 +272,9 @@ impl<'a> Renderer<'a> {
let outro_svg = self.target.join("outro.svg"); let outro_svg = self.target.join("outro.svg");
fs::write( fs::write(
&outro_svg, &outro_svg,
outro(source_res).to_string_pretty().into_bytes() outro(&project.lecture.lang, source_res)
.to_string_pretty()
.into_bytes()
)?; )?;
let outro_mkv = self.outro_mkv(); let outro_mkv = self.outro_mkv();
svg2mkv(metadata, outro_svg, outro_mkv, self.format, OUTRO_LEN)?; svg2mkv(metadata, outro_svg, outro_mkv, self.format, OUTRO_LEN)?;

View file

@ -57,26 +57,6 @@ pub fn format_date(d: Date) -> String {
format!("{:02}{:02}{:02}", d.year % 100, d.month, d.day) format!("{:02}{:02}{:02}", d.year % 100, d.month, d.day)
} }
/// Format a date in DD. MMMM YYYY format.
pub fn format_date_long(d: Date) -> String {
let month = match d.month {
1 => "Januar",
2 => "Februar",
3 => "März",
4 => "April",
5 => "Mai",
6 => "Juni",
7 => "Juli",
8 => "August",
9 => "September",
10 => "Oktober",
11 => "November",
12 => "Dezember",
_ => unreachable!()
};
format!("{:02}. {month} {:04}", d.day, d.year)
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord)] #[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub struct Time { pub struct Time {
pub seconds: u32, pub seconds: u32,