Skip to content
Snippets Groups Projects
Unverified Commit cd705c11 authored by Dominic Meiser's avatar Dominic Meiser
Browse files

language support

parent f5ec5db4
No related branches found
No related tags found
No related merge requests found
//! 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 { ...@@ -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 { ...@@ -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()
......
...@@ -12,6 +12,7 @@ use crate::{ ...@@ -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 { ...@@ -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 { ...@@ -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() { ...@@ -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,
......
...@@ -272,7 +272,9 @@ impl<'a> Renderer<'a> { ...@@ -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)?;
......
...@@ -57,26 +57,6 @@ pub fn format_date(d: Date) -> String { ...@@ -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,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment