titlekit 1.2.1 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -31,7 +31,7 @@ module Titlekit
31
31
  subtitle = {}
32
32
 
33
33
  fields = line.text_value.split(',')
34
-
34
+
35
35
  subtitle[:id] = elements.index(line) + 1
36
36
  subtitle[:start] = SSA.parse_timecode(fields[1])
37
37
  subtitle[:end] = SSA.parse_timecode(fields[2])
@@ -40,7 +40,7 @@ module Titlekit
40
40
  subtitle
41
41
  end
42
42
  end
43
- end
43
+ end
44
44
 
45
45
  # Parses the supplied string and builds the resulting subtitles array.
46
46
  #
@@ -59,8 +59,8 @@ module Titlekit
59
59
  failure += "failure_column #{parser.failure_column}\n"
60
60
  failure += "failure_reason #{parser.failure_reason}\n"
61
61
 
62
- raise failure
63
- end
62
+ fail failure
63
+ end
64
64
  end
65
65
 
66
66
  # Master the subtitles for best possible usage of the format's features.
@@ -70,8 +70,8 @@ module Titlekit
70
70
  tracks = subtitles.map { |subtitle| subtitle[:track] }.uniq
71
71
 
72
72
  if tracks.length == 1
73
-
74
- # maybe styling? aside that: nada más!
73
+
74
+ # maybe styling? aside that: nothing more!
75
75
 
76
76
  elsif (2..3).include?(tracks.length)
77
77
 
@@ -99,21 +99,23 @@ module Titlekit
99
99
 
100
100
  frames.each do |frame|
101
101
  intersecting = subtitles.select do |subtitle|
102
- (subtitle[:end] == frame[:end] || subtitle[:start] == frame[:start] ||
103
- (subtitle[:start] < frame[:start] && subtitle[:end] > frame[:end]))
102
+ subtitle[:end] == frame[:end] ||
103
+ subtitle[:start] == frame[:start] ||
104
+ (subtitle[:start] < frame[:start] && subtitle[:end] > frame[:end])
104
105
  end
105
106
 
106
107
  if intersecting.any?
107
108
  intersecting.sort_by! { |subtitle| tracks.index(subtitle[:track]) }
108
109
  intersecting.each do |subtitle|
109
- new_subtitle = {}
110
- new_subtitle[:id] = mastered_subtitles.length+1
111
- new_subtitle[:start] = frame[:start]
112
- new_subtitle[:end] = frame[:end]
110
+ color = tracks.index(subtitle[:track]) % DEFAULT_PALETTE.length
113
111
 
114
- color = DEFAULT_PALETTE[tracks.index(subtitle[:track]) % DEFAULT_PALETTE.length]
115
- new_subtitle[:style] = color
116
- new_subtitle[:lines] = subtitle[:lines]
112
+ new_subtitle = {
113
+ id: mastered_subtitles.length + 1,
114
+ start: frame[:start],
115
+ end: frame[:end],
116
+ style: DEFAULT_PALETTE[color],
117
+ lines: subtitle[:lines]
118
+ }
117
119
 
118
120
  mastered_subtitles << new_subtitle
119
121
  end
@@ -137,13 +139,13 @@ module Titlekit
137
139
  result << "Style: Default,Arial,16,16777215,16777215,16777215,-2147483640,0,0,1,3,0,2,70,70,40,0,0\n"
138
140
  result << "Style: Middle,Arial,16,16777215,16777215,16777215,-2147483640,0,0,1,3,0,10,70,70,40,0,0\n"
139
141
  result << "Style: Top,Arial,16,16777215,16777215,16777215,-2147483640,0,0,1,3,0,6,70,70,40,0,0\n"
140
-
142
+
141
143
  DEFAULT_PALETTE.each do |color|
142
144
  # reordered_color = ""
143
145
  # reordered_color << color[4..5]
144
146
  # reordered_color << color[2..3]
145
147
  # reordered_color << color[0..1]\
146
- processed_color = (color[4..5]+color[2..3]+color[0..1]).to_i(16)
148
+ processed_color = (color[4..5] + color[2..3] + color[0..1]).to_i(16)
147
149
  result << "Style: #{color},Arial,16,#{processed_color},#{processed_color},#{processed_color},-2147483640,0,0,1,3,0,2,70,70,40,0,0\n"
148
150
  end
149
151
 
@@ -160,14 +162,14 @@ module Titlekit
160
162
  '0000', # MarginL
161
163
  '0000', # MarginR
162
164
  '0000', # MarginV
163
- '',# Effect
165
+ '', # Effect
164
166
  subtitle[:lines].gsub("\n", '\N') # Text
165
167
  ]
166
168
 
167
169
  result << (fields.join(',') + "\n")
168
170
  end
169
171
 
170
- return result
172
+ result
171
173
  end
172
174
 
173
175
  protected
@@ -177,20 +179,20 @@ module Titlekit
177
179
  # @param seconds [Float] an amount of seconds
178
180
  # @return [String] An SSA-formatted timecode ('h:mm:ss.ms')
179
181
  def self.build_timecode(seconds)
180
- sprintf("%01d:%02d:%02d.%s",
181
- seconds / 3600,
182
- (seconds%3600) / 60,
183
- seconds % 60,
184
- sprintf("%.2f", seconds)[-2, 3])
185
- end
182
+ format('%01d:%02d:%02d.%s',
183
+ seconds / 3600,
184
+ (seconds % 3600) / 60,
185
+ seconds % 60,
186
+ format('%.2f', seconds)[-2, 3])
187
+ end
186
188
 
187
189
  # Parses an SSA-formatted timecode into a float representing seconds
188
190
  #
189
191
  # @param timecode [String] An SSA-formatted timecode ('h:mm:ss.ms')
190
192
  # @param [Float] an amount of seconds
191
193
  def self.parse_timecode(timecode)
192
- mres = timecode.match(/(?<h>\d):(?<m>\d{2}):(?<s>\d{2})[:|\.](?<ms>\d+)/)
193
- return "#{mres["h"].to_i * 3600 + mres["m"].to_i * 60 + mres["s"].to_i}.#{mres["ms"]}".to_f
194
- end
194
+ m = timecode.match(/(?<h>\d):(?<m>\d{2}):(?<s>\d{2})[:|\.](?<ms>\d+)/)
195
+ m['h'].to_i * 3600 + m['m'].to_i * 60 + m['s'].to_i + "0.#{m['ms']}".to_f
196
+ end
195
197
  end
196
- end
198
+ end
@@ -12,7 +12,7 @@ module Titlekit
12
12
  @subtitles = []
13
13
  @track = nil
14
14
 
15
- return self
15
+ self
16
16
  end
17
17
 
18
18
  # Specifies the encoding you have or want.
@@ -31,7 +31,7 @@ module Titlekit
31
31
  # Specifies the file (path) you have or want.
32
32
  #
33
33
  # @param [String] A string specifying the path to the file
34
- # @return If you omit the argument, it returns the already specified path
34
+ # @return If you omit the argument, it returns the already specified path
35
35
  def file(*args)
36
36
  if args.empty?
37
37
  return @file
@@ -44,7 +44,7 @@ module Titlekit
44
44
  # Specifies the track the subtitles should be assigned to.
45
45
  #
46
46
  # @param [String] A string specifying the track identifier
47
- # @return If you omit the argument, it returns the already specified track
47
+ # @return If you omit the argument, it returns the already specified track
48
48
  def track(*args)
49
49
  if args.empty?
50
50
  return @track
@@ -52,7 +52,7 @@ module Titlekit
52
52
  @track = args[0]
53
53
  return self
54
54
  end
55
- end
55
+ end
56
56
 
57
57
  # Specifies the framerate you have or want.
58
58
  #
@@ -69,7 +69,7 @@ module Titlekit
69
69
 
70
70
  # Returns all named references you have specified
71
71
  def references
72
- return @references
72
+ @references
73
73
  end
74
74
 
75
75
  # Places a named reference (in the form of a string or a symbol)
@@ -85,7 +85,7 @@ module Titlekit
85
85
  #
86
86
  # @example Referencing a timecode by hours
87
87
  # have.reference('Earl grey, hot', hours: 0.963)
88
- #
88
+ #
89
89
  # @example Referencing a timecode by seconds
90
90
  # have.reference('In a galaxy ...', seconds: 14.2)
91
91
  #
@@ -97,7 +97,7 @@ module Titlekit
97
97
  #
98
98
  # @example Referencing a timecode by an SSA-style timecode
99
99
  # have.reference('In a galaxy ...', ssa_timecode: '0:00:14,20')
100
- #
100
+ #
101
101
  # @example Symbols can be used as references as well!
102
102
  # have.reference(:narrator_begins, minutes: 9.6)
103
103
  #
@@ -107,7 +107,7 @@ module Titlekit
107
107
  # @param seconds [Float]
108
108
  # @param milliseconds [Float]
109
109
  def reference(name,
110
- *args,
110
+ *_args,
111
111
  hours: nil,
112
112
  minutes: nil,
113
113
  seconds: nil,
@@ -116,24 +116,25 @@ module Titlekit
116
116
  ssa_timecode: nil,
117
117
  ass_timecode: nil)
118
118
 
119
- @references[name] = case
120
- when hours
121
- { timecode: hours * 3600 }
122
- when minutes
123
- { timecode: minutes * 60 }
124
- when seconds
125
- { timecode: seconds }
126
- when milliseconds
127
- { timecode: milliseconds / 1000 }
128
- when srt_timecode
129
- { timecode: Titlekit::SRT.parse_timecode(srt_timecode) }
130
- when ssa_timecode
131
- { timecode: Titlekit::SSA.parse_timecode(ssa_timecode) }
132
- when ass_timecode
133
- { timecode: Titlekit::ASS.parse_timecode(ass_timecode) }
134
- end
119
+ @references[name] =
120
+ case
121
+ when hours
122
+ { timecode: hours * 3600 }
123
+ when minutes
124
+ { timecode: minutes * 60 }
125
+ when seconds
126
+ { timecode: seconds }
127
+ when milliseconds
128
+ { timecode: milliseconds / 1000 }
129
+ when srt_timecode
130
+ { timecode: Titlekit::SRT.parse_timecode(srt_timecode) }
131
+ when ssa_timecode
132
+ { timecode: Titlekit::SSA.parse_timecode(ssa_timecode) }
133
+ when ass_timecode
134
+ { timecode: Titlekit::ASS.parse_timecode(ass_timecode) }
135
+ end
135
136
 
136
- return self
137
- end
137
+ self
138
+ end
138
139
  end
139
- end
140
+ end
@@ -2,5 +2,5 @@ module Titlekit
2
2
  # The default palette is used to distinguish simultaneous subtitles
3
3
  # by their color (if distinguishing them by different position is either
4
4
  # not possible due to the format or not sensible in the specific case)
5
- DEFAULT_PALETTE = %w{EDF393 F5E665 FFC472 FFA891 89BABE}
6
- end
5
+ DEFAULT_PALETTE = %w(EDF393 F5E665 FFC472 FFA891 89BABE)
6
+ end
@@ -1,4 +1,4 @@
1
1
  module Titlekit
2
2
  # Versioning follows the semantic versioning scheme: http://semver.org/
3
- VERSION = '1.2.1'
4
- end
3
+ VERSION = '1.2.2'
4
+ end
data/lib/titlekit/want.rb CHANGED
@@ -21,4 +21,4 @@ module Titlekit
21
21
  end
22
22
  end
23
23
  end
24
- end
24
+ end
data/lib/titlekit.rb CHANGED
@@ -6,4 +6,4 @@ require 'titlekit/specification'
6
6
  require 'titlekit/have'
7
7
  require 'titlekit/want'
8
8
  require 'titlekit/job'
9
- require 'titlekit/version'
9
+ require 'titlekit/version'
data/spec/ass_spec.rb CHANGED
@@ -9,7 +9,7 @@ describe Titlekit::ASS do
9
9
  Titlekit::ASS.import(File.read('spec/files/ass/simple.ass'))
10
10
  end
11
11
 
12
- it 'parses and builds 3 subtitles' do
12
+ it 'parses and builds 2 subtitles' do
13
13
  expect(subtitles.length).to eq(2)
14
14
  end
15
15
 
@@ -23,7 +23,7 @@ describe Titlekit::ASS do
23
23
  end
24
24
 
25
25
  it 'parses and builds correct lines' do
26
- expect(subtitles[1][:lines]).to eq("Est-ce vraiment Naruto ?")
26
+ expect(subtitles[1][:lines]).to eq('Est-ce vraiment Naruto ?')
27
27
  end
28
28
  end
29
29
 
@@ -32,7 +32,7 @@ describe Titlekit::ASS do
32
32
  Titlekit::ASS.import(File.read('spec/files/ass/hard.ass'))
33
33
  end
34
34
 
35
- it 'parses and builds 3 subtitles' do
35
+ it 'parses and builds 17 subtitles' do
36
36
  expect(subtitles.length).to eq(17)
37
37
  end
38
38
 
@@ -49,6 +49,29 @@ describe Titlekit::ASS do
49
49
  expect(subtitles[1][:lines]).to eq("هل تعمل اللغة العربية؟\n")
50
50
  end
51
51
  end
52
+
53
+ context 'with a file including a BOM' do
54
+ let(:subtitles) do
55
+ Titlekit::ASS.import(File.read('spec/files/ass/bom.ass'))
56
+ end
57
+
58
+ it 'parses and builds 2 subtitles' do
59
+ expect(subtitles.length).to eq(2)
60
+ end
61
+
62
+ it 'parses and builds correct ids' do
63
+ expect(subtitles[0][:id]).to eq(1)
64
+ end
65
+
66
+ it 'parses and builds correct timecodes' do
67
+ expect(subtitles[1][:start]).to eq(120.99)
68
+ expect(subtitles[1][:end]).to eq(122.87)
69
+ end
70
+
71
+ it 'parses and builds correct lines' do
72
+ expect(subtitles[1][:lines]).to eq('Agreed.')
73
+ end
74
+ end
52
75
  end
53
76
 
54
77
  describe '.export' do
@@ -101,13 +124,13 @@ Dialogue: 0,0:00:01.50,0:00:03.70,Default,,0000,0000,0000,,Oh yeah ... 寧為太
101
124
 
102
125
  describe '.build_timecode' do
103
126
  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')
127
+ expect(Titlekit::ASS.build_timecode(35.9678)).to eq('0:00:35.97')
105
128
  end
106
129
  end
107
130
 
108
131
  describe '.parse_timecode' do
109
132
  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)
133
+ expect(Titlekit::ASS.parse_timecode('0:00:35.96')).to eq(35.96)
111
134
  end
112
- end
113
- end
135
+ end
136
+ end
@@ -3,10 +3,10 @@ require File.join(File.expand_path(__dir__), '../spec_helper')
3
3
  describe Titlekit::Job do
4
4
 
5
5
  describe 'Automatic grouping' do
6
-
6
+
7
7
  context 'with an implicit single track' do
8
8
  before(:all) do
9
- @ins = %w{one two}.map do |file|
9
+ @ins = %w(one two).map do |file|
10
10
  File.join(__dir__, 'single_track', "#{file}.srt")
11
11
  end
12
12
  @out = File.join(__dir__, 'single_track', 'out.srt')
@@ -19,7 +19,7 @@ describe Titlekit::Job do
19
19
  job = Titlekit::Job.new
20
20
  @ins.each { |file| job.have.file(file).encoding('UTF-8') }
21
21
  job.want.file(@out)
22
-
22
+
23
23
  expect(job.run).to be true
24
24
  end
25
25
 
@@ -28,9 +28,9 @@ describe Titlekit::Job do
28
28
  end
29
29
  end
30
30
 
31
- context 'with implicit dual tracks' do
31
+ context 'with implicit dual tracks' do
32
32
  before(:all) do
33
- @ins = %w{one two}.map do |file|
33
+ @ins = %w(one two).map do |file|
34
34
  File.join(__dir__, 'dual_tracks', "#{file}.srt")
35
35
  end
36
36
  @out = File.join(__dir__, 'dual_tracks', 'out.srt')
@@ -43,13 +43,13 @@ describe Titlekit::Job do
43
43
  job = Titlekit::Job.new
44
44
  @ins.each { |file| job.have.file(file).encoding('UTF-8') }
45
45
  job.want.file(@out)
46
-
46
+
47
47
  expect(job.run).to be true
48
48
  end
49
49
 
50
50
  it 'delivers the expected output' do
51
51
  expect(FileUtils.compare_file(@out, @expected)).to be true
52
52
  end
53
- end
53
+ end
54
54
  end
55
- end
55
+ end
@@ -18,14 +18,14 @@ describe Titlekit::Job do
18
18
 
19
19
  have = job.have
20
20
  have.file(@in)
21
-
21
+
22
22
  want = job.want
23
23
  want.file(@out)
24
-
24
+
25
25
  job.run
26
26
 
27
27
  expect(job.report.join).to include('detected')
28
- end
28
+ end
29
29
  end
30
30
 
31
31
  context 'with exhibit B' do
@@ -43,12 +43,12 @@ describe Titlekit::Job do
43
43
 
44
44
  have = job.have
45
45
  have.file(@in)
46
-
46
+
47
47
  want = job.want
48
48
  want.file(@out)
49
49
 
50
50
  job.run
51
-
51
+
52
52
  expect(job.report.join).to include('detected')
53
53
  end
54
54
  end
@@ -68,14 +68,14 @@ describe Titlekit::Job do
68
68
 
69
69
  have = job.have
70
70
  have.file(@in)
71
-
71
+
72
72
  want = job.want
73
73
  want.file(@out)
74
-
74
+
75
75
  job.run
76
-
76
+
77
77
  expect(job.report.join).to include('detected')
78
78
  end
79
79
  end
80
80
  end
81
- end
81
+ end
@@ -0,0 +1,17 @@
1
+ [Script Info]
2
+ ; Script generated by Aegisub 3.2.2$
3
+ ; http://www.aegisub.org/$
4
+ Title: Default Aegisub file$
5
+ ScriptType: v4.00+$
6
+ WrapStyle: 0$
7
+ ScaledBorderAndShadow: yes$
8
+ YCbCr Matrix: None$
9
+
10
+ [V4+ Styles]
11
+ Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
12
+ Style: Default,Tahoma,16,&H00000000,&H00ffffff,&H00ffffff,&H00c0c0c0,-1,0,0,0,100,100,0,0.00,1,2,3,2,20,20,20,1
13
+
14
+ [Events]
15
+ Format: Layer, Start, End, Style, Actor, MarginL, MarginR, MarginV, Effect, Text
16
+ Dialogue: 0,0:01:41.70,0:01:46.84,Default,,0000,0000,0000,,Nevermind us, we are mostly only interested in whether the BOM at the start of the file is handled ok.
17
+ Dialogue: 0,0:02:00.99,0:02:02.87,Default,,0000,0000,0000,,Agreed.
@@ -3,7 +3,7 @@ require File.join(File.expand_path(__dir__), '../spec_helper')
3
3
  describe Titlekit::Job do
4
4
 
5
5
  describe 'Format conversion' do
6
-
6
+
7
7
  context 'From ASS to SRT' do
8
8
  before(:all) do
9
9
  @in = File.join(__dir__, 'ass_srt', 'in.ass')
@@ -18,10 +18,10 @@ describe Titlekit::Job do
18
18
 
19
19
  have = job.have
20
20
  have.file(@in)
21
-
21
+
22
22
  want = job.want
23
23
  want.file(@out)
24
-
24
+
25
25
  expect(job.run).to be true
26
26
  end
27
27
 
@@ -44,10 +44,10 @@ describe Titlekit::Job do
44
44
 
45
45
  have = job.have
46
46
  have.file(@in)
47
-
47
+
48
48
  want = job.want
49
49
  want.file(@out)
50
-
50
+
51
51
  expect(job.run).to be true
52
52
  end
53
53
 
@@ -70,7 +70,7 @@ describe Titlekit::Job do
70
70
 
71
71
  have = job.have
72
72
  have.file(@in)
73
-
73
+
74
74
  want = job.want
75
75
  want.file(@out)
76
76
 
@@ -79,10 +79,10 @@ describe Titlekit::Job do
79
79
 
80
80
  it 'delivers the expected output' do
81
81
  expect(FileUtils.compare_file(@out, @expected)).to be true
82
- end
83
- end
82
+ end
83
+ end
84
84
 
85
- context 'From SSA to SRT' do
85
+ context 'From SSA to SRT' do
86
86
  before(:all) do
87
87
  @in = File.join(__dir__, 'ssa_srt', 'in.ssa')
88
88
  @out = File.join(__dir__, 'ssa_srt', 'out.srt')
@@ -91,22 +91,21 @@ describe Titlekit::Job do
91
91
  File.delete(@out) if File.exist?(@out)
92
92
  end
93
93
 
94
- it 'runs the job' do
94
+ it 'runs the job' do
95
95
  job = Titlekit::Job.new
96
96
 
97
97
  have = job.have
98
98
  have.file(@in)
99
-
99
+
100
100
  want = job.want
101
101
  want.file(@out)
102
-
102
+
103
103
  expect(job.run).to be true
104
104
  end
105
105
 
106
106
  it 'delivers the expected output' do
107
107
  expect(FileUtils.compare_file(@out, @expected)).to be true
108
- end
108
+ end
109
109
  end
110
-
111
110
  end
112
- end
111
+ end
data/spec/job_spec.rb CHANGED
@@ -16,7 +16,7 @@ describe Titlekit::Job do
16
16
 
17
17
  it 'returns an instance of Have' do
18
18
  expect(have).to be_a_kind_of(Titlekit::Have)
19
- end
19
+ end
20
20
  end
21
21
 
22
22
  context 'with a block, passing no variable' do
@@ -36,7 +36,7 @@ describe Titlekit::Job do
36
36
  expect(have.encoding).to eq('utf-8')
37
37
  expect(have.file).to be
38
38
  expect(have.fps).to eq(25)
39
- end
39
+ end
40
40
  end
41
41
 
42
42
  context 'with a block, passing a variable' do
@@ -108,7 +108,7 @@ describe Titlekit::Job do
108
108
  expect(want.encoding).to eq('utf-8')
109
109
  expect(want.file).to eq('out.srt')
110
110
  expect(want.fps).to eq(23.976)
111
- end
111
+ end
112
112
  end
113
113
  end
114
114
 
@@ -119,7 +119,7 @@ describe Titlekit::Job do
119
119
  job = Titlekit::Job.new
120
120
  job.have { file('something/that/without/doubt/wont/exist.srt') }
121
121
  job.want { file('something/that/does/not/matter/anyway.ass') }
122
-
122
+
123
123
  expect(job.run).to be false
124
124
  expect(job.report.join).to include('Failure while reading')
125
125
  end
@@ -130,7 +130,7 @@ describe Titlekit::Job do
130
130
  job = Titlekit::Job.new
131
131
  job.have { file('spec/files/srt/simple.srt') }
132
132
  job.want { file('!@#$%^&*()|?/\\.ass') }
133
-
133
+
134
134
  expect(job.run).to be false
135
135
  expect(job.report.join).to include('Failure while writing')
136
136
  end
@@ -141,22 +141,21 @@ describe Titlekit::Job do
141
141
  job = Titlekit::Job.new
142
142
  job.have { file('spec/files/try/unsupported.try') }
143
143
  job.want { file('!@#$%^&*()|?/\.ass') }
144
-
144
+
145
145
  expect(job.run).to be false
146
146
  expect(job.report.join).to include('Failure while importing TRY')
147
147
  end
148
- end
148
+ end
149
149
 
150
150
  context 'with an output format that is not supported' do
151
151
  it 'gracefully aborts the job' do
152
152
  job = Titlekit::Job.new
153
153
  job.have { file('spec/files/srt/simple.srt') }
154
154
  job.want { file('spec/files/try/unsupported-output.try') }
155
-
155
+
156
156
  expect(job.run).to be false
157
157
  expect(job.report.join).to include('Failure while exporting TRY')
158
158
  end
159
159
  end
160
-
161
160
  end
162
- end
161
+ end