titlekit 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|