#![warn(missing_docs)]
pub use anyhow::{Error, Result};
pub mod align;
pub mod clean;
pub mod contexts;
pub mod decode;
pub mod errors;
pub mod export;
pub mod import;
pub mod lang;
pub mod merge;
pub(crate) mod progress;
pub mod segment;
pub mod services;
pub mod srt;
pub mod time;
pub mod video;
peg::parser! {
grammar grammar() for str {
use std::str::FromStr;
use srt::{Subtitle, SubtitleFile};
use time::Period;
pub rule subtitle_file() -> SubtitleFile
= blank_lines()? result:subtitles() blank_lines()? {
SubtitleFile { subtitles: result }
}
rule subtitles() -> Vec<Subtitle>
= subs:subtitle() ** blank_lines() { subs }
rule subtitle() -> Subtitle
= index:digits() newline() p:time_period() newline() l:lines() {
Subtitle { index: index, period: p, lines: l }
}
rule time_period() -> Period
= begin:time() " --> " end:time() {?
let mut end = end;
if begin == end {
end += 0.001;
}
match Period::new(begin, end) {
Ok(p) => Ok(p),
Err(_) => Err("invalid time period"),
}
}
rule time() -> f32
= hh:digits() ":" mm:digits() ":" ss:comma_float() {
(hh as f32)*3600.0 + (mm as f32)*60.0 + ss
}
rule lines() -> Vec<String>
= lines:line() ** newline() { lines }
rule line() -> String
= text:$([^ '\r' | '\n']+) { text.to_string() }
rule digits() -> usize
= digits:$(['0'..='9']+) { FromStr::from_str(digits).unwrap() }
rule comma_float() -> f32
= float_str:$(['0'..='9']+ "," ['0'..='9']+) {
let fixed: String = float_str.replace(",", ".");
FromStr::from_str(&fixed).unwrap()
}
rule newline()
= "\r"? "\n"
rule blank_lines()
= newline()+
}
}