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
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 1b36a1f0921cdaa8ccdc52e9947507e17fa15000
|
|
4
|
+
data.tar.gz: c9925463a03d50b1486625d83e5df62ee4ab010a
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: d4eb3bf019168c863b72ed5c3eb05567ec5233fcfe71ca570f561fd08ad0da569f1bac69317f2c227c373144a05468e2efca751db90846e729fd47deb9741e03
|
|
7
|
+
data.tar.gz: 166c7fccd1d8085dba1cdf4c6eb49685d2ce20bdbb606fd58082dcd4e0e59c8dbd91f88474bd111ab58d431af0e062c0a11cfa128ce085c6def53ead5651b505
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2013 Simon Repp
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
# Titlekit [](https://travis-ci.org/simonrepp/titlekit)
|
|
2
|
+
|
|
3
|
+
Featureful Ruby 2 library for SRT / ASS / SSA subtitles
|
|
4
|
+
|
|
5
|
+
*Titlekit supports SRT, ASS and SSA, file format conversion, transcoding, automatic encoding detection, creation of simultaneous/multi-language subtitles, and timecode corrections with simple, progressive and framerate-based approaches. All of this is packed into a natural, dead-simple (and also irb-friendly) API.*
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
**Patch level 2.0.0-p195 is mandatory because it contains necessary bugfixes for the new keyword arguments.**
|
|
10
|
+
|
|
11
|
+
Add the `titlekit` gem to your gemfile or install it yourself:
|
|
12
|
+
|
|
13
|
+
$ gem install titlekit
|
|
14
|
+
|
|
15
|
+
### Optional installation recommendation
|
|
16
|
+
|
|
17
|
+
Titlekit uses [rchardet19](https://github.com/oleander/rchardet) to detect unknown encodings; There is another library for this task called [charlock_holmes](https://github.com/brianmario/charlock_holmes), which offers more robust detection algorithms, but is not included by default because it relies on external C libraries that can make its installation anywhere from semi-easy to impossible. If you want Titlekit to use *charlock_holmes*, install it yourself, and Titlekit will automatically use it over *rchardet19*!
|
|
18
|
+
|
|
19
|
+
## Documentation
|
|
20
|
+
|
|
21
|
+
### Basic example
|
|
22
|
+
|
|
23
|
+
A small hello world of Titlekit: **Converting from .srt to .ssa format**
|
|
24
|
+
|
|
25
|
+
```ruby
|
|
26
|
+
job = Titlekit::Job.new # (1) Initialize
|
|
27
|
+
job.have { file('existing.srt') } # (2) Specify what you have
|
|
28
|
+
job.want { file('converted.ssa') } # (3) Specify what you want
|
|
29
|
+
job.run # (4) Make it happen
|
|
30
|
+
```
|
|
31
|
+
### Checking success
|
|
32
|
+
|
|
33
|
+
The return value from `#run` will tell you if the job was a success. If it was not,
|
|
34
|
+
you can access `#report` to get messages related to the direct failure cause and also on
|
|
35
|
+
anything suspicious that might have happened before (e.g. Low confidence when detecting an
|
|
36
|
+
unknown encoding)
|
|
37
|
+
|
|
38
|
+
```ruby
|
|
39
|
+
if job.run
|
|
40
|
+
# hooray
|
|
41
|
+
else
|
|
42
|
+
puts job.report.join("\n")
|
|
43
|
+
end
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### All features by example
|
|
47
|
+
|
|
48
|
+
In all following examples I will omit `(1)` and `(4)` from the basic example, because they stay the same.
|
|
49
|
+
All the functionalities from all the following examples can be combined in any way you want.
|
|
50
|
+
|
|
51
|
+
#### Transcoding
|
|
52
|
+
|
|
53
|
+
```ruby
|
|
54
|
+
job.have do
|
|
55
|
+
file('input.srt')
|
|
56
|
+
encoding('ISO-8859-1')
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
job.want do
|
|
60
|
+
file('output.srt')
|
|
61
|
+
encoding('UTF-8')
|
|
62
|
+
end
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
#### Converting
|
|
66
|
+
|
|
67
|
+
```ruby
|
|
68
|
+
job.have { file('input.ass') }
|
|
69
|
+
job.want { file('output.srt') }
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
#### Simple timeshifting
|
|
73
|
+
|
|
74
|
+
```ruby
|
|
75
|
+
job.have do
|
|
76
|
+
file('input.srt')
|
|
77
|
+
reference('first sentence spoken', subtitle: 0)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
job.want do
|
|
81
|
+
file('output.srt')
|
|
82
|
+
reference('first sentence spoken', srt_timecode: '00:00:54,200')
|
|
83
|
+
end
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
#### Progressive timeshifting
|
|
87
|
+
|
|
88
|
+
```ruby
|
|
89
|
+
job.have do
|
|
90
|
+
file('input.srt')
|
|
91
|
+
reference('first subtitle', subtitle: 0)
|
|
92
|
+
reference('last subtitle', subtitle: 475)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
job.want do
|
|
96
|
+
file('output.srt')
|
|
97
|
+
reference('first subtitle', minutes: 3.76)
|
|
98
|
+
reference('last subtitle', hours: 1.8912)
|
|
99
|
+
end
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
#### Framerate-based timeshifting
|
|
103
|
+
|
|
104
|
+
```ruby
|
|
105
|
+
job.have do
|
|
106
|
+
file('input.srt')
|
|
107
|
+
fps(25)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
job.want do
|
|
111
|
+
file('output.srt')
|
|
112
|
+
fps(23.976)
|
|
113
|
+
end
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
#### Mixed mode timeshifting
|
|
117
|
+
|
|
118
|
+
```ruby
|
|
119
|
+
job.have do
|
|
120
|
+
file('input.srt')
|
|
121
|
+
fps(25)
|
|
122
|
+
reference(:first_sub, subtitle: 0)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
job.want do
|
|
126
|
+
file('output.srt')
|
|
127
|
+
fps(23.976)
|
|
128
|
+
reference(:first_sub, minute: 13.49)
|
|
129
|
+
end
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
#### Merging
|
|
133
|
+
|
|
134
|
+
Subtitles that don't overlap are automatically merged and treated as one track.
|
|
135
|
+
|
|
136
|
+
```ruby
|
|
137
|
+
job.have do
|
|
138
|
+
file('subs_chapter1.srt')
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
job.have do
|
|
142
|
+
file('subs_chapter2.srt')
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
job.want do
|
|
146
|
+
file('subs_both_chapters_combined.srt')
|
|
147
|
+
end
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
#### Merging (with time correction)
|
|
151
|
+
|
|
152
|
+
If each of your individual subtitle files contains timecodes relative to its own starting point,
|
|
153
|
+
you have to supply a reference so misaligned subtitles can be automatically shifted. When you fail
|
|
154
|
+
to do this, your subtitles overlap and thus Titlekit assumes that you want simultaneous subtitles (which are explained in the next paragraph below this one).
|
|
155
|
+
|
|
156
|
+
```ruby
|
|
157
|
+
job.have do
|
|
158
|
+
file('subs_cd1.srt')
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
job.have do
|
|
162
|
+
file('subs_cd2.srt')
|
|
163
|
+
reference(:cd2_subtitles_starting_at, minutes: 0)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
job.want do
|
|
167
|
+
reference(:cd2_subtitles_starting_at, srt_timecode: '00:01:24,000')
|
|
168
|
+
file('subs_both_cds_combined.srt')
|
|
169
|
+
end
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
#### Simultaneous/multi-lanugage subtitles
|
|
173
|
+
|
|
174
|
+
Subtitles that overlap are automatically treated as simultaneous/multi-lanugage subtitles.
|
|
175
|
+
Titlekit then positions and formats them in the most sensible way it sees fit.
|
|
176
|
+
|
|
177
|
+
```ruby
|
|
178
|
+
job.have { file('enlish.srt') }
|
|
179
|
+
job.have { file('dutch.srt') }
|
|
180
|
+
job.want { file('dual-language.srt') }
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Any target format is possible, Titlekit will automatically make the best use of the formatting
|
|
184
|
+
features your target format provides. Pick a sophisticated subtitle format, and your dual
|
|
185
|
+
subtitles will automatically be prettier and more readable!
|
|
186
|
+
|
|
187
|
+
```ruby
|
|
188
|
+
job.have { file('enlish.srt') }
|
|
189
|
+
job.have { file('dutch.srt') }
|
|
190
|
+
job.want { file('dual-language-prettier.ass') }
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
You can also go crazy if you want, Titlekit can handle it.
|
|
194
|
+
|
|
195
|
+
```ruby
|
|
196
|
+
job.have { file('enlish.srt') }
|
|
197
|
+
job.have { file('dutch.srt') }
|
|
198
|
+
job.have { file('spanish.srt') }
|
|
199
|
+
job.have { file('german.srt') }
|
|
200
|
+
job.have { file('italian.srt') }
|
|
201
|
+
job.have { file('french.srt') }
|
|
202
|
+
job.have { file('portuguese.srt') }
|
|
203
|
+
job.have { file('russian.srt') }
|
|
204
|
+
job.want { file('messy-but-supported.ssa') }
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
#### Mixed mode Merging (implicit)
|
|
208
|
+
|
|
209
|
+
If you really need the absurdly exotic case of merging multi-part subtitles into multiple simultaneous tracks, you just need to make sure you enter them in the correct order, which is: Lanuage1/Part1 -> Language1/Part2 -> Language2/Part1 -> Language2/Part2
|
|
210
|
+
|
|
211
|
+
```ruby
|
|
212
|
+
job.have { file('subs_english_chapter1.srt')
|
|
213
|
+
job.have { file('subs_english_chapter2.srt')
|
|
214
|
+
job.have { file('subs_french_chapter1.srt')
|
|
215
|
+
job.have { file('subs_french_chapter2.srt')
|
|
216
|
+
|
|
217
|
+
job.want do
|
|
218
|
+
file('subs_multi_part_multi_track.srt')
|
|
219
|
+
end
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
#### Mixed mode Merging (explicit)
|
|
223
|
+
|
|
224
|
+
If you supply explicit track identifiers by which to material should be grouped into tracks,
|
|
225
|
+
you can also forget all about the otherwise required order and just go wild:
|
|
226
|
+
|
|
227
|
+
```ruby
|
|
228
|
+
|
|
229
|
+
job.have do
|
|
230
|
+
file('subs_french_chapter2.srt')
|
|
231
|
+
track('le-french-track')
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
job.have do
|
|
235
|
+
file('subs_english_chapter1.srt')
|
|
236
|
+
track('the-english-one')
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
job.have do
|
|
240
|
+
file('subs_french_chapter1.srt')
|
|
241
|
+
track('le-french-track')
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
job.have do
|
|
245
|
+
file('subs_english_chapter2.srt')
|
|
246
|
+
track('the-english-one')
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
job.want do
|
|
250
|
+
file('subs_multi_part_multi_track.srt')
|
|
251
|
+
end
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
#### Multiple targets
|
|
255
|
+
|
|
256
|
+
```ruby
|
|
257
|
+
job.have { file('input.srt') }
|
|
258
|
+
job.want { file('output.ass') }
|
|
259
|
+
job.want { file('output.ssa') }
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
#### Templates
|
|
263
|
+
|
|
264
|
+
```ruby
|
|
265
|
+
job.have do
|
|
266
|
+
file('input.srt')
|
|
267
|
+
encoding('Shift_JIS')
|
|
268
|
+
reference(:some_subtitle, subtitle: 23)
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
templ = job.want do
|
|
272
|
+
file('output.srt')
|
|
273
|
+
encoding('UTF-8')
|
|
274
|
+
reference(:some_subtitle, hours: 0.16)
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
job.want(template: templ) { file('output.ass') }
|
|
278
|
+
job.want(template: templ) { file('output.ssa') }
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
#### Explicitly control encoding detection
|
|
282
|
+
|
|
283
|
+
```ruby
|
|
284
|
+
job.have do
|
|
285
|
+
file('input.srt')
|
|
286
|
+
encoding(:detect) # Detect the encoding with charlock_holmes if installed, otherwise rchardet19
|
|
287
|
+
# You don't need to supply this line though, it's the default behavior!
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
job.have do
|
|
291
|
+
file('input.srt')
|
|
292
|
+
encoding(:rchardet19) # Explicitly use rchardet19
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
job.have do
|
|
296
|
+
file('input.srt')
|
|
297
|
+
encoding(:charlock_holmes) # Explicitly use charlock_holmes
|
|
298
|
+
end
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
#### Syntax Variants
|
|
302
|
+
|
|
303
|
+
`#have` and `#want` offer three different syntax variants, which are functionally identical:
|
|
304
|
+
|
|
305
|
+
```ruby
|
|
306
|
+
job.have do
|
|
307
|
+
file('input.srt')
|
|
308
|
+
encoding('ISO-8859-1')
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
# is identical to
|
|
312
|
+
|
|
313
|
+
job.have do |have|
|
|
314
|
+
have.file('input.srt')
|
|
315
|
+
have.encoding('ISO-8859-1')
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
# is identical to
|
|
319
|
+
|
|
320
|
+
have = job.have
|
|
321
|
+
have.file('input.srt')
|
|
322
|
+
have.encoding('ISO-8859-1')
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
## API Reference
|
|
326
|
+
|
|
327
|
+
http://www.rubydoc.info/gems/titlekit/frames (or generate it yourself with YARD)
|
|
328
|
+
|
|
329
|
+
## Contributing
|
|
330
|
+
|
|
331
|
+
1. Fork it
|
|
332
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
333
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
|
334
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
335
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
module Titlekit
|
|
2
|
+
|
|
3
|
+
# Specifies existing input for a job.
|
|
4
|
+
class Have < Specification
|
|
5
|
+
|
|
6
|
+
def initialize
|
|
7
|
+
super
|
|
8
|
+
|
|
9
|
+
@encoding = :detect
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# @param [String, Symbol] A string specifying the encoding if it is known,
|
|
13
|
+
# (e.g. 'UTF-8', 'ISO-8859-1'), :detect in case you don't know, and
|
|
14
|
+
# :rchardet19 or :charlock_holmes if you have installed an additional
|
|
15
|
+
# detection library and want to specifically use one or the other.
|
|
16
|
+
#
|
|
17
|
+
# @return If you omit the argument, it returns the already specified encoding
|
|
18
|
+
def encoding(*args)
|
|
19
|
+
if args.empty?
|
|
20
|
+
return @encoding
|
|
21
|
+
else
|
|
22
|
+
@encoding = args[0]
|
|
23
|
+
return self
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Places a named reference (in the form of a string or a symbol) on
|
|
28
|
+
# either a +subtitle+ index or a timecode specified by either
|
|
29
|
+
# +hours+, +minutes+, +seconds+ or +milliseconds+.
|
|
30
|
+
#
|
|
31
|
+
# Its typical use-case is to reference a specific subtitle you can
|
|
32
|
+
# recognize in both the movie and your subtitle file, where usually
|
|
33
|
+
# for the subtitle file (represented by {Have}) you will reference
|
|
34
|
+
# the subtitle index and for the movie (represented by {Want}) you
|
|
35
|
+
# will reference the timecode that is displayed when the line occurs
|
|
36
|
+
# in the movie.
|
|
37
|
+
#
|
|
38
|
+
# @example Referencing a subtitle index (ZERO-INDEXED! First subtitle is 0)
|
|
39
|
+
# have.reference('Earl grey, hot', subtitle: 645)
|
|
40
|
+
#
|
|
41
|
+
# @example Referencing a timecode by seconds
|
|
42
|
+
# have.reference('In a galaxy ...', seconds: 14.2)
|
|
43
|
+
#
|
|
44
|
+
# @example Referencing a timecode by an SRT-style timecode
|
|
45
|
+
# have.reference('In a galaxy ...', srt_timecode: '00:00:14,200')
|
|
46
|
+
#
|
|
47
|
+
# @example Referencing a timecode by an ASS-style timecode
|
|
48
|
+
# have.reference('In a galaxy ...', ass_timecode: '0:00:14,20')
|
|
49
|
+
#
|
|
50
|
+
# @example Referencing a timecode by an SSA-style timecode
|
|
51
|
+
# have.reference('In a galaxy ...', ssa_timecode: '0:00:14,20')
|
|
52
|
+
#
|
|
53
|
+
# @example Symbols can be used as references as well!
|
|
54
|
+
# have.reference(:narrator_begins, minutes: 7.9)
|
|
55
|
+
#
|
|
56
|
+
# @param name [String, Symbol] The name of the reference
|
|
57
|
+
# @param subtitle [Integer] Heads up: Numbering starts at 1!
|
|
58
|
+
# @param hours [Float]
|
|
59
|
+
# @param minutes [Float]
|
|
60
|
+
# @param seconds [Float]
|
|
61
|
+
# @param milliseconds [Float]
|
|
62
|
+
def reference(name,
|
|
63
|
+
*args,
|
|
64
|
+
subtitle: nil,
|
|
65
|
+
hours: nil,
|
|
66
|
+
minutes: nil,
|
|
67
|
+
seconds: nil,
|
|
68
|
+
milliseconds: nil,
|
|
69
|
+
srt_timecode: nil,
|
|
70
|
+
ssa_timecode: nil,
|
|
71
|
+
ass_timecode: nil)
|
|
72
|
+
|
|
73
|
+
if subtitle
|
|
74
|
+
@references[name] = { subtitle: subtitle }
|
|
75
|
+
else
|
|
76
|
+
super(name,
|
|
77
|
+
hours: hours,
|
|
78
|
+
minutes: minutes,
|
|
79
|
+
seconds: seconds,
|
|
80
|
+
milliseconds: milliseconds,
|
|
81
|
+
srt_timecode: srt_timecode,
|
|
82
|
+
ssa_timecode: ssa_timecode,
|
|
83
|
+
ass_timecode: ass_timecode)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
return self
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
end
|