titlekit 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.travis.yml +3 -0
  4. data/Gemfile +3 -0
  5. data/LICENSE +22 -0
  6. data/README.md +335 -0
  7. data/Rakefile +8 -0
  8. data/lib/titlekit/have.rb +90 -0
  9. data/lib/titlekit/job.rb +446 -0
  10. data/lib/titlekit/parsers/ass.rb +175 -0
  11. data/lib/titlekit/parsers/ass.treetop +72 -0
  12. data/lib/titlekit/parsers/srt.rb +139 -0
  13. data/lib/titlekit/parsers/srt.treetop +73 -0
  14. data/lib/titlekit/parsers/ssa.rb +201 -0
  15. data/lib/titlekit/parsers/ssa.treetop +72 -0
  16. data/lib/titlekit/specification.rb +131 -0
  17. data/lib/titlekit/utilities.rb +3 -0
  18. data/lib/titlekit/version.rb +3 -0
  19. data/lib/titlekit/want.rb +24 -0
  20. data/lib/titlekit.rb +9 -0
  21. data/spec/ass_spec.rb +113 -0
  22. data/spec/automatic_grouping/automatic_grouping_spec.rb +55 -0
  23. data/spec/automatic_grouping/dual_tracks/expected.srt +15 -0
  24. data/spec/automatic_grouping/dual_tracks/one.srt +11 -0
  25. data/spec/automatic_grouping/dual_tracks/out.srt +15 -0
  26. data/spec/automatic_grouping/dual_tracks/two.srt +11 -0
  27. data/spec/automatic_grouping/single_track/expected.srt +24 -0
  28. data/spec/automatic_grouping/single_track/one.srt +11 -0
  29. data/spec/automatic_grouping/single_track/out.srt +24 -0
  30. data/spec/automatic_grouping/single_track/two.srt +11 -0
  31. data/spec/encoding_detection/a/in.ass +0 -0
  32. data/spec/encoding_detection/b/in.srt +2389 -0
  33. data/spec/encoding_detection/b/out.srt +2389 -0
  34. data/spec/encoding_detection/c/in.srt +5320 -0
  35. data/spec/encoding_detection/c/out.srt +5320 -0
  36. data/spec/encoding_detection/encoding_detection_spec.rb +81 -0
  37. data/spec/files/ass/authentic.ass +0 -0
  38. data/spec/files/ass/hard.ass +37 -0
  39. data/spec/files/ass/simple.ass +28 -0
  40. data/spec/files/srt/authentic.srt +2708 -0
  41. data/spec/files/srt/coordinates.srt +13 -0
  42. data/spec/files/srt/simple.srt +12 -0
  43. data/spec/files/ssa/simple.ssa +26 -0
  44. data/spec/files/try/unsupported-output.try +0 -0
  45. data/spec/files/try/unsupported.try +7 -0
  46. data/spec/format_conversion/ass_srt/expected.srt +2327 -0
  47. data/spec/format_conversion/ass_srt/in.ass +485 -0
  48. data/spec/format_conversion/ass_srt/out.srt +2327 -0
  49. data/spec/format_conversion/format_conversion_spec.rb +112 -0
  50. data/spec/format_conversion/srt_ass/expected.ass +19 -0
  51. data/spec/format_conversion/srt_ass/in.srt +12 -0
  52. data/spec/format_conversion/srt_ass/out.ass +19 -0
  53. data/spec/format_conversion/srt_ssa/expected.ssa +19 -0
  54. data/spec/format_conversion/srt_ssa/in.srt +12 -0
  55. data/spec/format_conversion/srt_ssa/out.ssa +19 -0
  56. data/spec/format_conversion/ssa_srt/expected.srt +9 -0
  57. data/spec/format_conversion/ssa_srt/in.ssa +26 -0
  58. data/spec/format_conversion/ssa_srt/out.srt +9 -0
  59. data/spec/job_spec.rb +162 -0
  60. data/spec/simultaneous_subtitles/dual/ass/expected.ass +22 -0
  61. data/spec/simultaneous_subtitles/dual/ass/out.ass +22 -0
  62. data/spec/simultaneous_subtitles/dual/one.srt +11 -0
  63. data/spec/simultaneous_subtitles/dual/srt/expected.srt +27 -0
  64. data/spec/simultaneous_subtitles/dual/srt/out.srt +27 -0
  65. data/spec/simultaneous_subtitles/dual/ssa/expected.ssa +22 -0
  66. data/spec/simultaneous_subtitles/dual/ssa/out.ssa +22 -0
  67. data/spec/simultaneous_subtitles/dual/two.srt +11 -0
  68. data/spec/simultaneous_subtitles/simultaneous_subtitles_spec.rb +220 -0
  69. data/spec/simultaneous_subtitles/triple/ass/expected.ass +25 -0
  70. data/spec/simultaneous_subtitles/triple/ass/out.ass +25 -0
  71. data/spec/simultaneous_subtitles/triple/one.srt +11 -0
  72. data/spec/simultaneous_subtitles/triple/srt/expected.srt +55 -0
  73. data/spec/simultaneous_subtitles/triple/srt/out.srt +55 -0
  74. data/spec/simultaneous_subtitles/triple/ssa/expected.ssa +25 -0
  75. data/spec/simultaneous_subtitles/triple/ssa/out.ssa +25 -0
  76. data/spec/simultaneous_subtitles/triple/three.srt +11 -0
  77. data/spec/simultaneous_subtitles/triple/two.srt +11 -0
  78. data/spec/simultaneous_subtitles/triple_plus/ass/expected.ass +93 -0
  79. data/spec/simultaneous_subtitles/triple_plus/ass/out.ass +93 -0
  80. data/spec/simultaneous_subtitles/triple_plus/five.srt +11 -0
  81. data/spec/simultaneous_subtitles/triple_plus/four.srt +11 -0
  82. data/spec/simultaneous_subtitles/triple_plus/one.srt +11 -0
  83. data/spec/simultaneous_subtitles/triple_plus/six.srt +11 -0
  84. data/spec/simultaneous_subtitles/triple_plus/srt/expected.srt +149 -0
  85. data/spec/simultaneous_subtitles/triple_plus/srt/out.srt +149 -0
  86. data/spec/simultaneous_subtitles/triple_plus/ssa/expected.ssa +93 -0
  87. data/spec/simultaneous_subtitles/triple_plus/ssa/out.ssa +93 -0
  88. data/spec/simultaneous_subtitles/triple_plus/three.srt +11 -0
  89. data/spec/simultaneous_subtitles/triple_plus/two.srt +11 -0
  90. data/spec/spec_helper.rb +7 -0
  91. data/spec/specifications_spec.rb +138 -0
  92. data/spec/srt_spec.rb +134 -0
  93. data/spec/ssa_spec.rb +90 -0
  94. data/spec/timecode_correction/double_reference/expected.srt +13 -0
  95. data/spec/timecode_correction/double_reference/in.srt +12 -0
  96. data/spec/timecode_correction/double_reference/out.srt +13 -0
  97. data/spec/timecode_correction/framerate/expected.srt +5 -0
  98. data/spec/timecode_correction/framerate/in.srt +4 -0
  99. data/spec/timecode_correction/framerate/out.srt +5 -0
  100. data/spec/timecode_correction/framerate_plus_reference/expected.srt +13 -0
  101. data/spec/timecode_correction/framerate_plus_reference/in.srt +12 -0
  102. data/spec/timecode_correction/framerate_plus_reference/out.srt +13 -0
  103. data/spec/timecode_correction/single_reference/expected.srt +13 -0
  104. data/spec/timecode_correction/single_reference/in.srt +12 -0
  105. data/spec/timecode_correction/single_reference/out.srt +13 -0
  106. data/spec/timecode_correction/timecode_correction_spec.rb +124 -0
  107. data/spec/transcoding/gb2312-ascii/in.srt +12 -0
  108. data/spec/transcoding/iso-8859-1_utf-8/expected.srt +12 -0
  109. data/spec/transcoding/iso-8859-1_utf-8/in.srt +11 -0
  110. data/spec/transcoding/iso-8859-1_utf-8/out.srt +12 -0
  111. data/spec/transcoding/transcoding_spec.rb +116 -0
  112. data/spec/transcoding/utf-8_gbk/expected.srt +12 -0
  113. data/spec/transcoding/utf-8_gbk/in.srt +11 -0
  114. data/spec/transcoding/utf-8_gbk/out.srt +12 -0
  115. data/spec/transcoding/windows-1252_utf-8/expected.srt +12 -0
  116. data/spec/transcoding/windows-1252_utf-8/in.srt +11 -0
  117. data/spec/transcoding/windows-1252_utf-8/out.srt +12 -0
  118. data/titlekit.gemspec +28 -0
  119. 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,11 @@
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
@@ -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,11 @@
1
+ 1
2
+ 00:00:02,000 --> 00:00:10,000
3
+ See? Things carry over
4
+
5
+ 2
6
+ 00:00:12,000 --> 00:00:20,000
7
+ I am so tired oh man
8
+
9
+ 3
10
+ 00:00:22,000 --> 00:00:30,000
11
+ Writing specs is fun lololol
@@ -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,11 @@
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
@@ -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,11 @@
1
+ 1
2
+ 00:00:32,000 --> 00:00:40,000
3
+ See? Things carry over
4
+
5
+ 2
6
+ 00:00:42,000 --> 00:00:50,000
7
+ I am so tired oh man
8
+
9
+ 3
10
+ 00:00:52,000 --> 00:00:60,000
11
+ Writing specs is fun lololol
Binary file