Sync subtitles: Difference between revisions
Content added Content deleted
m (→{{header|Phix}}: added read_lines()/write_lines() remark) |
(Add Rust) |
||
Line 1,106: | Line 1,106: | ||
{{out}} |
{{out}} |
||
<pre>Same as FreeBASIC entry.</pre> |
<pre>Same as FreeBASIC entry.</pre> |
||
=={{header|Rust}}== |
|||
{{libheader|chrono}} |
|||
{{libheader|lazy_static}} |
|||
{{libheader|regex}} |
|||
<syntaxhighlight lang="rust"> |
|||
use chrono::{NaiveTime, TimeDelta}; |
|||
use lazy_static::lazy_static; |
|||
use regex::Regex; |
|||
use std::env; |
|||
use std::fs::File; |
|||
use std::io::{self, BufRead}; |
|||
use std::io::{stdout, Write}; |
|||
use std::path::Path; |
|||
lazy_static! { |
|||
static ref RE: Regex = |
|||
Regex::new(r"(\d{2}:\d{2}:\d{2},\d{3})\s+-->\s+(\d{2}:\d{2}:\d{2},\d{3})").unwrap(); |
|||
static ref FORMAT: String = String::from("%H:%M:%S,%3f"); |
|||
} |
|||
fn main() -> Result<(), Box<dyn std::error::Error>> { |
|||
let args: Vec<String> = env::args().collect(); |
|||
match args.len() { |
|||
3 => { |
|||
let path = &args[1]; |
|||
let secs: i64 = args[2].parse()?; |
|||
let mut lock = stdout().lock(); |
|||
for line in sync_file(path, secs)? { |
|||
writeln!(lock, "{line}").unwrap() |
|||
} |
|||
} |
|||
_ => println!("usage: subrip-sync <filename> <seconds>"), |
|||
} |
|||
Ok(()) |
|||
} |
|||
fn sync_file<P>(path: P, secs: i64) -> Result<impl Iterator<Item = String>, io::Error> |
|||
where |
|||
P: AsRef<Path>, |
|||
{ |
|||
let file = File::open(path)?; |
|||
let reader = io::BufReader::new(file); |
|||
Ok(sync_lines(reader.lines().flatten(), secs)) |
|||
} |
|||
fn sync_lines(lines: impl Iterator<Item = String>, secs: i64) -> impl Iterator<Item = String> { |
|||
let delta = TimeDelta::new(secs, 0).unwrap(); |
|||
lines.map(move |line| { |
|||
if let Some(groups) = RE.captures(&line) { |
|||
format(&groups[1], &groups[2], &delta) |
|||
} else { |
|||
line |
|||
} |
|||
}) |
|||
} |
|||
fn format(start: &str, stop: &str, delta: &TimeDelta) -> String { |
|||
format!( |
|||
"{} --> {}", |
|||
(NaiveTime::parse_from_str(start, &FORMAT).unwrap() + *delta).format(&FORMAT), |
|||
(NaiveTime::parse_from_str(stop, &FORMAT).unwrap() + *delta).format(&FORMAT) |
|||
) |
|||
} |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
$ subrip-sync movie.srt 9 > movie_plus_9.srt |
|||
$ cat movie_plus_9.srt |
|||
1 |
|||
00:01:40,550 --> 00:01:45,347 |
|||
Four billion years ago, |
|||
the first marine life forms. |
|||
2 |
|||
00:01:45,555 --> 00:01:51,019 |
|||
First came the fish...then slowly |
|||
other life forms evolved. |
|||
3 |
|||
00:01:51,144 --> 00:01:52,979 |
|||
Therefore, our ancestors... |
|||
4 |
|||
00:01:52,979 --> 00:01:54,898 |
|||
...came from fish. |
|||
5 |
|||
00:01:55,232 --> 00:01:56,608 |
|||
Everyone, come and see this. |
|||
6 |
|||
00:01:56,733 --> 00:01:59,361 |
|||
Cretaceous Tyrannosaurus. |
|||
7 |
|||
00:01:59,736 --> 00:02:01,488 |
|||
Ferocious! |
|||
8 |
|||
00:02:07,035 --> 00:02:07,869 |
|||
Red, |
|||
9 |
|||
00:02:08,203 --> 00:02:09,079 |
|||
Pong! |
|||
10 |
|||
00:02:11,540 --> 00:02:12,999 |
|||
Isn't this a gecko? |
|||
11 |
|||
00:02:13,416 --> 00:02:16,419 |
|||
How else can I get a 15 ton T-Rex in here? |
|||
12 |
|||
00:02:16,503 --> 00:02:20,048 |
|||
With our advanced technology, I shrank it down. |
|||
</pre> |
|||
=={{header|Wren}}== |
=={{header|Wren}}== |