titlekit 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.travis.yml +3 -0
- data/Gemfile +3 -0
- data/LICENSE +22 -0
- data/README.md +335 -0
- data/Rakefile +8 -0
- data/lib/titlekit/have.rb +90 -0
- data/lib/titlekit/job.rb +446 -0
- data/lib/titlekit/parsers/ass.rb +175 -0
- data/lib/titlekit/parsers/ass.treetop +72 -0
- data/lib/titlekit/parsers/srt.rb +139 -0
- data/lib/titlekit/parsers/srt.treetop +73 -0
- data/lib/titlekit/parsers/ssa.rb +201 -0
- data/lib/titlekit/parsers/ssa.treetop +72 -0
- data/lib/titlekit/specification.rb +131 -0
- data/lib/titlekit/utilities.rb +3 -0
- data/lib/titlekit/version.rb +3 -0
- data/lib/titlekit/want.rb +24 -0
- data/lib/titlekit.rb +9 -0
- data/spec/ass_spec.rb +113 -0
- data/spec/automatic_grouping/automatic_grouping_spec.rb +55 -0
- data/spec/automatic_grouping/dual_tracks/expected.srt +15 -0
- data/spec/automatic_grouping/dual_tracks/one.srt +11 -0
- data/spec/automatic_grouping/dual_tracks/out.srt +15 -0
- data/spec/automatic_grouping/dual_tracks/two.srt +11 -0
- data/spec/automatic_grouping/single_track/expected.srt +24 -0
- data/spec/automatic_grouping/single_track/one.srt +11 -0
- data/spec/automatic_grouping/single_track/out.srt +24 -0
- data/spec/automatic_grouping/single_track/two.srt +11 -0
- data/spec/encoding_detection/a/in.ass +0 -0
- data/spec/encoding_detection/b/in.srt +2389 -0
- data/spec/encoding_detection/b/out.srt +2389 -0
- data/spec/encoding_detection/c/in.srt +5320 -0
- data/spec/encoding_detection/c/out.srt +5320 -0
- data/spec/encoding_detection/encoding_detection_spec.rb +81 -0
- data/spec/files/ass/authentic.ass +0 -0
- data/spec/files/ass/hard.ass +37 -0
- data/spec/files/ass/simple.ass +28 -0
- data/spec/files/srt/authentic.srt +2708 -0
- data/spec/files/srt/coordinates.srt +13 -0
- data/spec/files/srt/simple.srt +12 -0
- data/spec/files/ssa/simple.ssa +26 -0
- data/spec/files/try/unsupported-output.try +0 -0
- data/spec/files/try/unsupported.try +7 -0
- data/spec/format_conversion/ass_srt/expected.srt +2327 -0
- data/spec/format_conversion/ass_srt/in.ass +485 -0
- data/spec/format_conversion/ass_srt/out.srt +2327 -0
- data/spec/format_conversion/format_conversion_spec.rb +112 -0
- data/spec/format_conversion/srt_ass/expected.ass +19 -0
- data/spec/format_conversion/srt_ass/in.srt +12 -0
- data/spec/format_conversion/srt_ass/out.ass +19 -0
- data/spec/format_conversion/srt_ssa/expected.ssa +19 -0
- data/spec/format_conversion/srt_ssa/in.srt +12 -0
- data/spec/format_conversion/srt_ssa/out.ssa +19 -0
- data/spec/format_conversion/ssa_srt/expected.srt +9 -0
- data/spec/format_conversion/ssa_srt/in.ssa +26 -0
- data/spec/format_conversion/ssa_srt/out.srt +9 -0
- data/spec/job_spec.rb +162 -0
- data/spec/simultaneous_subtitles/dual/ass/expected.ass +22 -0
- data/spec/simultaneous_subtitles/dual/ass/out.ass +22 -0
- data/spec/simultaneous_subtitles/dual/one.srt +11 -0
- data/spec/simultaneous_subtitles/dual/srt/expected.srt +27 -0
- data/spec/simultaneous_subtitles/dual/srt/out.srt +27 -0
- data/spec/simultaneous_subtitles/dual/ssa/expected.ssa +22 -0
- data/spec/simultaneous_subtitles/dual/ssa/out.ssa +22 -0
- data/spec/simultaneous_subtitles/dual/two.srt +11 -0
- data/spec/simultaneous_subtitles/simultaneous_subtitles_spec.rb +220 -0
- data/spec/simultaneous_subtitles/triple/ass/expected.ass +25 -0
- data/spec/simultaneous_subtitles/triple/ass/out.ass +25 -0
- data/spec/simultaneous_subtitles/triple/one.srt +11 -0
- data/spec/simultaneous_subtitles/triple/srt/expected.srt +55 -0
- data/spec/simultaneous_subtitles/triple/srt/out.srt +55 -0
- data/spec/simultaneous_subtitles/triple/ssa/expected.ssa +25 -0
- data/spec/simultaneous_subtitles/triple/ssa/out.ssa +25 -0
- data/spec/simultaneous_subtitles/triple/three.srt +11 -0
- data/spec/simultaneous_subtitles/triple/two.srt +11 -0
- data/spec/simultaneous_subtitles/triple_plus/ass/expected.ass +93 -0
- data/spec/simultaneous_subtitles/triple_plus/ass/out.ass +93 -0
- data/spec/simultaneous_subtitles/triple_plus/five.srt +11 -0
- data/spec/simultaneous_subtitles/triple_plus/four.srt +11 -0
- data/spec/simultaneous_subtitles/triple_plus/one.srt +11 -0
- data/spec/simultaneous_subtitles/triple_plus/six.srt +11 -0
- data/spec/simultaneous_subtitles/triple_plus/srt/expected.srt +149 -0
- data/spec/simultaneous_subtitles/triple_plus/srt/out.srt +149 -0
- data/spec/simultaneous_subtitles/triple_plus/ssa/expected.ssa +93 -0
- data/spec/simultaneous_subtitles/triple_plus/ssa/out.ssa +93 -0
- data/spec/simultaneous_subtitles/triple_plus/three.srt +11 -0
- data/spec/simultaneous_subtitles/triple_plus/two.srt +11 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/specifications_spec.rb +138 -0
- data/spec/srt_spec.rb +134 -0
- data/spec/ssa_spec.rb +90 -0
- data/spec/timecode_correction/double_reference/expected.srt +13 -0
- data/spec/timecode_correction/double_reference/in.srt +12 -0
- data/spec/timecode_correction/double_reference/out.srt +13 -0
- data/spec/timecode_correction/framerate/expected.srt +5 -0
- data/spec/timecode_correction/framerate/in.srt +4 -0
- data/spec/timecode_correction/framerate/out.srt +5 -0
- data/spec/timecode_correction/framerate_plus_reference/expected.srt +13 -0
- data/spec/timecode_correction/framerate_plus_reference/in.srt +12 -0
- data/spec/timecode_correction/framerate_plus_reference/out.srt +13 -0
- data/spec/timecode_correction/single_reference/expected.srt +13 -0
- data/spec/timecode_correction/single_reference/in.srt +12 -0
- data/spec/timecode_correction/single_reference/out.srt +13 -0
- data/spec/timecode_correction/timecode_correction_spec.rb +124 -0
- data/spec/transcoding/gb2312-ascii/in.srt +12 -0
- data/spec/transcoding/iso-8859-1_utf-8/expected.srt +12 -0
- data/spec/transcoding/iso-8859-1_utf-8/in.srt +11 -0
- data/spec/transcoding/iso-8859-1_utf-8/out.srt +12 -0
- data/spec/transcoding/transcoding_spec.rb +116 -0
- data/spec/transcoding/utf-8_gbk/expected.srt +12 -0
- data/spec/transcoding/utf-8_gbk/in.srt +11 -0
- data/spec/transcoding/utf-8_gbk/out.srt +12 -0
- data/spec/transcoding/windows-1252_utf-8/expected.srt +12 -0
- data/spec/transcoding/windows-1252_utf-8/in.srt +11 -0
- data/spec/transcoding/windows-1252_utf-8/out.srt +12 -0
- data/titlekit.gemspec +28 -0
- metadata +313 -0
data/spec/ass_spec.rb
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
require File.join(File.expand_path(__dir__), 'spec_helper')
|
2
|
+
|
3
|
+
describe Titlekit::ASS do
|
4
|
+
|
5
|
+
describe '.import' do
|
6
|
+
|
7
|
+
context 'with a simple file' do
|
8
|
+
let(:subtitles) do
|
9
|
+
Titlekit::ASS.import(File.read('spec/files/ass/simple.ass'))
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'parses and builds 3 subtitles' do
|
13
|
+
expect(subtitles.length).to eq(2)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'parses and builds correct ids' do
|
17
|
+
expect(subtitles[0][:id]).to eq(1)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'parses and builds correct timecodes' do
|
21
|
+
expect(subtitles[1][:start]).to eq(120.99)
|
22
|
+
expect(subtitles[1][:end]).to eq(122.87)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'parses and builds correct lines' do
|
26
|
+
expect(subtitles[1][:lines]).to eq("Est-ce vraiment Naruto ?")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'with a hard file' do
|
31
|
+
let(:subtitles) do
|
32
|
+
Titlekit::ASS.import(File.read('spec/files/ass/hard.ass'))
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'parses and builds 3 subtitles' do
|
36
|
+
expect(subtitles.length).to eq(17)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'parses and builds correct ids' do
|
40
|
+
expect(subtitles[0][:id]).to eq(1)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'parses and builds correct timecodes' do
|
44
|
+
expect(subtitles[8][:start]).to eq(4)
|
45
|
+
expect(subtitles[8][:end]).to eq(6)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'parses and builds correct lines' do
|
49
|
+
expect(subtitles[1][:lines]).to eq("هل تعمل اللغة العربية؟\n")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe '.export' do
|
55
|
+
it 'should export valid ASS' do
|
56
|
+
subtitles = [
|
57
|
+
{
|
58
|
+
start: 1.5,
|
59
|
+
end: 3.7,
|
60
|
+
lines: 'Eine feine Testung haben sie da!'
|
61
|
+
},
|
62
|
+
{
|
63
|
+
id: 2,
|
64
|
+
start: 1.5,
|
65
|
+
end: 3.7,
|
66
|
+
lines: '¡Sí claro! Pero que lastima que no es 100% español ...'
|
67
|
+
},
|
68
|
+
{
|
69
|
+
id: 3,
|
70
|
+
start: 1.5,
|
71
|
+
end: 3.7,
|
72
|
+
lines: 'Oh yeah ... 寧為太平犬,不做亂世人'
|
73
|
+
}
|
74
|
+
]
|
75
|
+
|
76
|
+
expected = <<-EXPECTED
|
77
|
+
[Script Info]
|
78
|
+
ScriptType: v4.00+
|
79
|
+
|
80
|
+
[V4+ Styles]
|
81
|
+
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
|
82
|
+
Style: Default,Arial,16,&H00FFFFFF,&H00FFFFFF,&H40000000,&H40000000,0,0,0,0,100,100,0,0.00,1,3,0,2,20,20,20,1
|
83
|
+
Style: Top,Arial,16,&H00FFFFFF,&H00FFFFFF,&H40000000,&H40000000,0,0,0,0,100,100,0,0.00,1,3,0,8,20,20,20,1
|
84
|
+
Style: Middle,Arial,16,&H00FFFFFF,&H00FFFFFF,&H40000000,&H40000000,0,0,0,0,100,100,0,0.00,1,3,0,5,20,20,20,1
|
85
|
+
Style: EDF393,Arial,16,&H0093F3ED,&H0093F3ED,&H40000000,&H40000000,0,0,0,0,100,100,0,0.00,1,3,0,2,20,20,20,1
|
86
|
+
Style: F5E665,Arial,16,&H0065E6F5,&H0065E6F5,&H40000000,&H40000000,0,0,0,0,100,100,0,0.00,1,3,0,2,20,20,20,1
|
87
|
+
Style: FFC472,Arial,16,&H0072C4FF,&H0072C4FF,&H40000000,&H40000000,0,0,0,0,100,100,0,0.00,1,3,0,2,20,20,20,1
|
88
|
+
Style: FFA891,Arial,16,&H0091A8FF,&H0091A8FF,&H40000000,&H40000000,0,0,0,0,100,100,0,0.00,1,3,0,2,20,20,20,1
|
89
|
+
Style: 89BABE,Arial,16,&H00BEBA89,&H00BEBA89,&H40000000,&H40000000,0,0,0,0,100,100,0,0.00,1,3,0,2,20,20,20,1
|
90
|
+
|
91
|
+
[Events]
|
92
|
+
Format: Layer, Start, End, Style, Actor, MarginL, MarginR, MarginV, Effect, Text
|
93
|
+
Dialogue: 0,0:00:01.50,0:00:03.70,Default,,0000,0000,0000,,Eine feine Testung haben sie da!
|
94
|
+
Dialogue: 0,0:00:01.50,0:00:03.70,Default,,0000,0000,0000,,¡Sí claro! Pero que lastima que no es 100% español ...
|
95
|
+
Dialogue: 0,0:00:01.50,0:00:03.70,Default,,0000,0000,0000,,Oh yeah ... 寧為太平犬,不做亂世人
|
96
|
+
EXPECTED
|
97
|
+
|
98
|
+
expect(Titlekit::ASS.export(subtitles)).to eq(expected)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe '.build_timecode' do
|
103
|
+
it 'builds an ASS timecode from a float timecode value' do
|
104
|
+
expect(Titlekit::ASS.build_timecode(35.9678)).to eq('0:00:35.97')
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe '.parse_timecode' do
|
109
|
+
it 'obtains a float timecode value from an ASS timecode' do
|
110
|
+
expect(Titlekit::ASS.parse_timecode('0:00:35.96')).to eq(35.96)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require File.join(File.expand_path(__dir__), '../spec_helper')
|
2
|
+
|
3
|
+
describe Titlekit::Job do
|
4
|
+
|
5
|
+
describe 'Automatic grouping' do
|
6
|
+
|
7
|
+
context 'with an implicit single track' do
|
8
|
+
before(:all) do
|
9
|
+
@ins = %w{one two}.map do |file|
|
10
|
+
File.join(__dir__, 'single_track', "#{file}.srt")
|
11
|
+
end
|
12
|
+
@out = File.join(__dir__, 'single_track', 'out.srt')
|
13
|
+
@expected = File.join(__dir__, 'single_track', 'expected.srt')
|
14
|
+
|
15
|
+
File.delete(@out) if File.exist?(@out)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'runs the job' do
|
19
|
+
job = Titlekit::Job.new
|
20
|
+
@ins.each { |file| job.have.file(file).encoding('UTF-8') }
|
21
|
+
job.want.file(@out)
|
22
|
+
|
23
|
+
expect(job.run).to be_true
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'delivers the expected output' do
|
27
|
+
expect(FileUtils.compare_file(@out, @expected)).to be_true
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'with implicit dual tracks' do
|
32
|
+
before(:all) do
|
33
|
+
@ins = %w{one two}.map do |file|
|
34
|
+
File.join(__dir__, 'dual_tracks', "#{file}.srt")
|
35
|
+
end
|
36
|
+
@out = File.join(__dir__, 'dual_tracks', 'out.srt')
|
37
|
+
@expected = File.join(__dir__, 'dual_tracks', 'expected.srt')
|
38
|
+
|
39
|
+
File.delete(@out) if File.exist?(@out)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'runs the job' do
|
43
|
+
job = Titlekit::Job.new
|
44
|
+
@ins.each { |file| job.have.file(file).encoding('UTF-8') }
|
45
|
+
job.want.file(@out)
|
46
|
+
|
47
|
+
expect(job.run).to be_true
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'delivers the expected output' do
|
51
|
+
expect(FileUtils.compare_file(@out, @expected)).to be_true
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
1
|
2
|
+
00:00:02,000 --> 00:00:10,000
|
3
|
+
<font color="#EDF393">This is a continuity of sorts</font>
|
4
|
+
<font color="#F5E665">See? Things carry over</font>
|
5
|
+
|
6
|
+
2
|
7
|
+
00:00:12,000 --> 00:00:20,000
|
8
|
+
<font color="#EDF393">It starts here</font>
|
9
|
+
<font color="#F5E665">I am so tired oh man</font>
|
10
|
+
|
11
|
+
3
|
12
|
+
00:00:22,000 --> 00:00:30,000
|
13
|
+
<font color="#EDF393">And ends there</font>
|
14
|
+
<font color="#F5E665">Writing specs is fun lololol</font>
|
15
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
1
|
2
|
+
00:00:02,000 --> 00:00:10,000
|
3
|
+
<font color="#EDF393">This is a continuity of sorts</font>
|
4
|
+
<font color="#F5E665">See? Things carry over</font>
|
5
|
+
|
6
|
+
2
|
7
|
+
00:00:12,000 --> 00:00:20,000
|
8
|
+
<font color="#EDF393">It starts here</font>
|
9
|
+
<font color="#F5E665">I am so tired oh man</font>
|
10
|
+
|
11
|
+
3
|
12
|
+
00:00:22,000 --> 00:00:30,000
|
13
|
+
<font color="#EDF393">And ends there</font>
|
14
|
+
<font color="#F5E665">Writing specs is fun lololol</font>
|
15
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
1
|
2
|
+
00:00:02,000 --> 00:00:10,000
|
3
|
+
This is a continuity of sorts
|
4
|
+
|
5
|
+
2
|
6
|
+
00:00:12,000 --> 00:00:20,000
|
7
|
+
It starts here
|
8
|
+
|
9
|
+
3
|
10
|
+
00:00:22,000 --> 00:00:30,000
|
11
|
+
And ends there
|
12
|
+
|
13
|
+
4
|
14
|
+
00:00:32,000 --> 00:00:40,000
|
15
|
+
See? Things carry over
|
16
|
+
|
17
|
+
5
|
18
|
+
00:00:42,000 --> 00:00:50,000
|
19
|
+
I am so tired oh man
|
20
|
+
|
21
|
+
6
|
22
|
+
00:00:52,000 --> 00:01:00,000
|
23
|
+
Writing specs is fun lololol
|
24
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
1
|
2
|
+
00:00:02,000 --> 00:00:10,000
|
3
|
+
This is a continuity of sorts
|
4
|
+
|
5
|
+
2
|
6
|
+
00:00:12,000 --> 00:00:20,000
|
7
|
+
It starts here
|
8
|
+
|
9
|
+
3
|
10
|
+
00:00:22,000 --> 00:00:30,000
|
11
|
+
And ends there
|
12
|
+
|
13
|
+
4
|
14
|
+
00:00:32,000 --> 00:00:40,000
|
15
|
+
See? Things carry over
|
16
|
+
|
17
|
+
5
|
18
|
+
00:00:42,000 --> 00:00:50,000
|
19
|
+
I am so tired oh man
|
20
|
+
|
21
|
+
6
|
22
|
+
00:00:52,000 --> 00:01:00,000
|
23
|
+
Writing specs is fun lololol
|
24
|
+
|
Binary file
|