vtt2ass 0.2.8 → 0.2.13

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.
@@ -86,7 +86,7 @@
86
86
 
87
87
 
88
88
 
89
- <strong class="classes">Classes:</strong> <span class='object_link'><a href="ASSFile.html" title="ASSFile (class)">ASSFile</a></span>, <span class='object_link'><a href="ASSStyle.html" title="ASSStyle (class)">ASSStyle</a></span>, <span class='object_link'><a href="ASSSubtitle.html" title="ASSSubtitle (class)">ASSSubtitle</a></span>, <span class='object_link'><a href="Application.html" title="Application (class)">Application</a></span>, <span class='object_link'><a href="VTTSubtitle.html" title="VTTSubtitle (class)">VTTSubtitle</a></span>
89
+ <strong class="classes">Classes:</strong> <span class='object_link'><a href="ASSFile.html" title="ASSFile (class)">ASSFile</a></span>, <span class='object_link'><a href="ASSLine.html" title="ASSLine (class)">ASSLine</a></span>, <span class='object_link'><a href="ASSStyle.html" title="ASSStyle (class)">ASSStyle</a></span>, <span class='object_link'><a href="ASSStyleParams.html" title="ASSStyleParams (class)">ASSStyleParams</a></span>, <span class='object_link'><a href="Application.html" title="Application (class)">Application</a></span>, <span class='object_link'><a href="VTTFile.html" title="VTTFile (class)">VTTFile</a></span>, <span class='object_link'><a href="VTTLine.html" title="VTTLine (class)">VTTLine</a></span>
90
90
 
91
91
 
92
92
  </p>
@@ -102,9 +102,9 @@
102
102
  </div>
103
103
 
104
104
  <div id="footer">
105
- Generated on Thu Jan 14 00:31:16 2021 by
105
+ Generated on Tue Mar 23 21:07:02 2021 by
106
106
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
107
- 0.9.26 (ruby-2.7.2).
107
+ 0.9.26 (ruby-3.0.0).
108
108
  </div>
109
109
 
110
110
  </div>
data/lib/vtt2ass.rb CHANGED
@@ -1,42 +1,109 @@
1
1
  # Imports
2
- require 'optparse'
2
+ require 'tty-option'
3
3
 
4
4
  # Relative imports
5
5
  require_relative 'vtt2ass/version'
6
6
  require_relative 'vtt2ass/Application'
7
7
 
8
+ class Command
9
+ include TTY::Option
10
+
11
+ usage do
12
+ header 'VTT2ASS'
13
+ program 'vtt2ass'
14
+ command ''
15
+ desc 'Convert VTT subtitles to ASS subtitles'
16
+ example "Convert files in a specific directory",
17
+ " $ vtt2ass ./path/to/file_input ./path/to/file_output"
18
+ end
19
+
20
+ # ------------------------------
21
+ # Arguments
22
+ # ------------------------------
23
+
24
+ argument :input do
25
+ optional
26
+ desc "Input directory or file (default: current directory)"
27
+ end
28
+
29
+ argument :output do
30
+ optional
31
+ desc "Output directory (default: console output)"
32
+ end
33
+
34
+ # ------------------------------
35
+ # Flags
36
+ # ------------------------------
37
+
38
+ flag :help do
39
+ short "-h"
40
+ long "--help"
41
+ desc "Print usage"
42
+ end
43
+
44
+ flag :version do
45
+ short "-v"
46
+ long "--version"
47
+ desc "Show version"
48
+ end
49
+
50
+ flag :quiet do
51
+ short "-q"
52
+ long "--quiet"
53
+ desc "Prevent the command from outputing to the console"
54
+ end
55
+
56
+ flag :noout do
57
+ short "-x"
58
+ long "--noout"
59
+ desc "Prevents the command from writing the resulting file(s) to the output folder"
60
+ end
61
+
62
+ # ------------------------------
63
+ # Options
64
+ # ------------------------------
65
+
66
+ option :title do
67
+ optional
68
+ short "-t STRING"
69
+ long "--title STRING"
70
+ desc "Specify a title for you file. If the input is a directory, all files will share the same title."
71
+ end
72
+
73
+ option :font_size do
74
+ optional
75
+ short "-s INTEGER"
76
+ long "--font-size INTEGER"
77
+ desc "Specify a font size for the subtitles (default: 52)"
78
+ end
79
+
80
+ option :font_family do
81
+ optional
82
+ short "-f STRING"
83
+ long "--font-family STRING"
84
+ desc "Specify a font family for the subtitles (default: 'Open Sans Semibold')"
85
+ end
86
+
87
+ def run
88
+ if params[:help] then
89
+ print help
90
+ exit
91
+ elsif params[:version] then
92
+ puts Vtt2ass::VERSION
93
+ exit
94
+ else
95
+ runner = Application.new(params)
96
+ # pp params.to_h
97
+ runner.start
98
+ end
99
+ end
100
+ end
101
+
8
102
  module Vtt2ass
9
- ##
10
- # This function creates a new application instance and starts the process.
11
- #
12
- # It also defines the arguments that can be provided from the CLI.
13
103
  def main
14
- options = {}
15
-
16
- OptionParser.new do |opts|
17
- opts.banner = "Usage: vtt2ass [options]"
18
- opts.separator ""
19
- opts.separator "Specific options:"
20
- opts.on("-i", "--input PATH", "Specify a custom input file or directory (default: './')") do |file_path|
21
- options[:input] = file_path
22
- end
23
- opts.on("-o", "--output PATH", "Specify a custom output directory (default: './')") do |file_path|
24
- options[:output] = file_path
25
- end
26
- opts.on("-f", "--font-family FONT", String, "Specify a font family for the subtitles (default: 'Open Sans Semibold')") do |font_family|
27
- options[:font_family] = font_family
28
- end
29
- opts.on("-s", "--font-size SIZE", Integer, "Specify a font size for the subtitles (default: 52)") do |font_size|
30
- options[:font_size] = font_size
31
- end
32
- opts.on("-v", "--version", "Show version") do
33
- puts Vtt2ass::VERSION
34
- exit
35
- end
36
- end.parse!
37
-
38
- app = Application.new(options)
39
- app.start
104
+ app = Command.new
105
+ app.parse
106
+ app.run
40
107
  end
41
108
 
42
109
  module_function :main
@@ -8,6 +8,8 @@ class ASSFile
8
8
  attr_reader :title, :width, :height
9
9
  attr_accessor :ass_styles, :ass_lines
10
10
 
11
+ ##
12
+ # Creates a new ASSFile instance and assigns the default values of instance variables.
11
13
  def initialize(title, width, height)
12
14
  @width = width
13
15
  @height = height
@@ -34,12 +36,16 @@ class ASSFile
34
36
  @ass_lines = []
35
37
  end
36
38
 
39
+ ##
40
+ # This method receives a VTTFile object and font arguments creates new ASSLine with the params of
41
+ # each VTTLine. All those ASSLine are stored in an array. It also creates an array of ASSStyle that
42
+ # will be used in the ASS style list.
37
43
  def convertVTTtoASS(vtt_file, font_family, font_size)
38
44
  vtt_file.lines.each do |line|
39
45
  @ass_lines.push(ASSLine.new(line.style, line.time_start, line.time_end, line.text))
40
46
  style_exists = false
41
47
  @ass_styles.each do |style|
42
- if (style.style_name == line.style) then
48
+ if (style.style_name.eql? line.style) then
43
49
  style_exists = true
44
50
  break
45
51
  end
@@ -50,6 +56,8 @@ class ASSFile
50
56
  end
51
57
  end
52
58
 
59
+ ##
60
+ # This method writes the content of the ASSFile object into a file path that is provided.
53
61
  def writeToFile(file_path)
54
62
  File.open(file_path, 'w') do |line|
55
63
  line.print "\ufeff"
@@ -83,7 +83,7 @@ class ASSLine
83
83
  end
84
84
 
85
85
  ##
86
- # The method pads text so that time numbers are a fixed number of digit.
86
+ # This method pads text so that time numbers are a fixed number of digit.
87
87
  #
88
88
  # * Requires +sep+, a string separator.
89
89
  # * Requires +input+, an integer.
@@ -20,6 +20,9 @@ class ASSStyle
20
20
  @font_size = font_size
21
21
  @style_name = style_name
22
22
  @s_params = ASSStyleParams.new(params, width, height)
23
+ if style_name.eql? 'MainTop' then
24
+ @s_params.vertical_margin = 50
25
+ end
23
26
  end
24
27
 
25
28
  ##
@@ -1,8 +1,12 @@
1
1
  ##
2
2
  # This class defines the ASS style parameters from VTT cue settings.
3
3
  class ASSStyleParams
4
- attr_reader :horizontal_margin, :vertical_margin, :alignment, :align
4
+ attr_accessor :horizontal_margin, :vertical_margin, :alignment, :align
5
5
 
6
+ ##
7
+ # Creates an instance of ASSStyleParams
8
+ # It takes VTT style arguments and assign them to their respectful instance variable.
9
+ # It calls methods to create ASS values from the VTT cue settings.
6
10
  def initialize(params, width, height)
7
11
  (params.split(' ').map { |p| p.split(':') }).each do |p|
8
12
  case p[0]
@@ -20,6 +24,9 @@ class ASSStyleParams
20
24
  createVerticalMargin(height)
21
25
  end
22
26
 
27
+ ##
28
+ # This method decides the alignement value in a 9 position grid based of the
29
+ # values in cue settings "align" and "line".
23
30
  def createAlignment()
24
31
  if (defined?(@line) and not defined?(@position)) then
25
32
  if (defined?(@align)) then
@@ -50,6 +57,9 @@ class ASSStyleParams
50
57
  end
51
58
  end
52
59
 
60
+ ##
61
+ # This method calculates the horizontal margin in px between the alignement position and
62
+ # and the content displayed by using the "position" cue setting.
53
63
  def createHorizontalMargin(width)
54
64
  steps = (width / 100).to_i
55
65
  if defined?(@position) then
@@ -59,6 +69,9 @@ class ASSStyleParams
59
69
  end
60
70
  end
61
71
 
72
+ ##
73
+ # This method calculates the vertical margin in px between the alignement position and
74
+ # and the content displayed by using the "line" cue setting.
62
75
  def createVerticalMargin(height)
63
76
  steps = (height / 100).to_i
64
77
  if defined?(@line) then
@@ -1,6 +1,3 @@
1
- # Imports
2
- require 'os'
3
-
4
1
  # Relative imports
5
2
  require_relative 'VTTFile'
6
3
  require_relative 'ASSFile'
@@ -13,12 +10,17 @@ class Application
13
10
  # Creates a new Application instance.
14
11
  # It receives +options+ that can define the input and output directories.
15
12
  def initialize(options)
16
- @input = options[:input] ? options[:input].gsub('\\', '/') : "./"
17
- @output = options[:output] ? options[:output].gsub('\\', '/') : "./"
13
+ @input = options[:input] ? options[:input].gsub('\\', '/').delete_suffix('/') : "."
14
+ @output = options[:output] ? options[:output].gsub('\\', '/').delete_suffix('/') : "."
18
15
  @width = 1920
19
16
  @height = 1080
20
17
  @font_family = options[:font_family] ? options[:font_family] : 'Open Sans Semibold'
21
18
  @font_size = options[:font_size] ? options[:font_size] : 52
19
+ if options[:title] then
20
+ @title = options[:title]
21
+ end
22
+ @quiet = options[:quiet]
23
+ @noout = options[:noout]
22
24
  end
23
25
 
24
26
  ##
@@ -28,18 +30,31 @@ class Application
28
30
  def start
29
31
  if File.directory?(@input) then
30
32
  Dir["#{@input}/*.vtt"].each do |file_path|
31
- vtt_to_ass(file_path).writeToFile(File.basename(file_path).gsub('.vtt', '.ass'))
33
+ convert(file_path)
32
34
  end
33
35
  elsif File.file?(@input) then
34
- vtt_to_ass(@input).writeToFile(@output + File.basename(@input).gsub('.vtt', '.ass'))
36
+ convert(@input)
35
37
  else
36
38
  puts 'Error: input file or directory does not exist.'
37
39
  end
38
40
  end
39
41
 
42
+ def convert(input_path)
43
+ ass_file = vtt_to_ass(input_path)
44
+ ass_file.writeToFile(@output + '/' + File.basename(input_path).gsub('.vtt', '.ass')) unless @noout
45
+ puts ass_file.to_s unless @quiet
46
+ end
47
+
48
+ ##
49
+ # This method creates a new VTTFile object from the file path provided and convert its content
50
+ # inside a new ASSFile object.
40
51
  def vtt_to_ass(file_path)
41
- vtt_file = VTTFile.new(file_path)
42
- ass_file = ASSFile.new(File.basename(file_path).gsub('.vtt', ''), @width, @height)
52
+ vtt_file = VTTFile.new(file_path, @width, @height)
53
+ ass_file = ASSFile.new(
54
+ (defined?(@title) ? @title : File.basename(file_path).gsub('.vtt', '')),
55
+ @width,
56
+ @height
57
+ )
43
58
  ass_file.convertVTTtoASS(vtt_file, @font_family, @font_size)
44
59
  return ass_file
45
60
  end
@@ -1,6 +1,3 @@
1
- # Imports
2
- require 'os'
3
-
4
1
  # Relative imports
5
2
  require_relative 'VTTLine'
6
3
 
@@ -9,19 +6,32 @@ require_relative 'VTTLine'
9
6
  class VTTFile
10
7
  attr_accessor :lines
11
8
 
12
- def initialize(file_path)
9
+ ##
10
+ # Creates a new VTTFile instance and assigns the default values of instance variables.
11
+ def initialize(file_path, width, height)
13
12
  @title = File.basename(file_path).gsub('.vtt', '')
14
13
  @lines = []
15
- separator = OS.posix? ? "\r\n\r\n": "\n\n"
14
+ separator = determine_line_ending(file_path) ? "\n\n" : "\r\n\r\n"
15
+ count = 0
16
16
  File.foreach(file_path, separator) do |paragraph|
17
- paragraph = paragraph.rstrip.gsub(/\r\n/, "\n")
17
+ paragraph = paragraph.rstrip.gsub(/[\r\n]/, "\n")
18
18
  if not paragraph.eql? "" then
19
- @lines.push(VTTLine.new(paragraph))
19
+ vtt_line = VTTLine.new(paragraph, width, height)
20
+ @lines.push(vtt_line)
21
+ count += 1
20
22
  end
21
23
  end
22
24
  @lines.shift
23
25
  end
24
26
 
27
+ def determine_line_ending(file_path)
28
+ File.open(file_path, 'r') do |file|
29
+ return file.readline[/\r?\n$/] == "\n"
30
+ end
31
+ end
32
+
33
+ ##
34
+ # This method writes the content of the VTTFile object into a file path that is provided.
25
35
  def writeToFile(file_path)
26
36
  File.open(file_path, 'w') do |line|
27
37
  line.print "\ufeff"
@@ -29,6 +39,8 @@ class VTTFile
29
39
  end
30
40
  end
31
41
 
42
+ ##
43
+ # This method concatenates the object data in the right order for a string output.
32
44
  def to_s
33
45
  return "WEBVTT\n\n\n" + @lines
34
46
  end
@@ -7,7 +7,7 @@ class VTTLine
7
7
  # This method creates an instance of an VTTLine.
8
8
  #
9
9
  # * Requires +paragraph+, a VTT formatted string as input.
10
- def initialize(paragraph)
10
+ def initialize(paragraph, width, height)
11
11
  lines = paragraph.split("\n")
12
12
  rx = /^([\d:.]*) --> ([\d:.]*)\s?(.*?)\s*$/
13
13
  @style = "Main"
@@ -22,7 +22,8 @@ class VTTLine
22
22
  @time_start = m[1]
23
23
  @time_end = m[2]
24
24
  @params = m[3]
25
- if @params.include? "align:middle line:7%" then
25
+ ass_style = ASSStyleParams.new(@params, width, height)
26
+ if @style.eql? 'Main' and ass_style.alignment == 8 then
26
27
  @style = "MainTop"
27
28
  end
28
29
  else
@@ -30,6 +31,8 @@ class VTTLine
30
31
  end
31
32
  count += 1;
32
33
  end
34
+
35
+ @text = @text.lstrip
33
36
  end
34
37
 
35
38
  ##
@@ -1,3 +1,8 @@
1
+ ##
2
+ # Vtt2ass module to provide the version number
1
3
  module Vtt2ass
2
- VERSION = "0.2.8"
4
+ ##
5
+ # This is the version of the application.
6
+ # This needs to be changed for each gem release.
7
+ VERSION = "0.2.13"
3
8
  end
data/vtt2ass.gemspec CHANGED
@@ -25,10 +25,10 @@ Gem::Specification.new do |spec|
25
25
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
26
  spec.require_paths = ["lib"]
27
27
 
28
- spec.add_dependency 'os'
29
- spec.add_dependency 'htmlentities'
28
+ spec.add_dependency 'htmlentities', '~> 4.3'
29
+ spec.add_dependency 'tty-option', '~> 0.1'
30
30
 
31
- spec.add_development_dependency 'rake'
32
- spec.add_development_dependency 'minitest'
33
- spec.add_development_dependency 'yard'
31
+ spec.add_development_dependency 'rake', '~> 12.0'
32
+ spec.add_development_dependency 'minitest', '~> 5.0'
33
+ spec.add_development_dependency 'yard', '~> 0.9'
34
34
  end
metadata CHANGED
@@ -1,85 +1,85 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vtt2ass
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.8
4
+ version: 0.2.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Louis-Philippe Fortin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-21 00:00:00.000000000 Z
11
+ date: 2021-05-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: os
14
+ name: htmlentities
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '4.3'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '4.3'
27
27
  - !ruby/object:Gem::Dependency
28
- name: htmlentities
28
+ name: tty-option
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '0.1'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '0.1'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '12.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: '12.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: minitest
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: '5.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: '5.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: yard
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ">="
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '0'
75
+ version: '0.9'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ">="
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '0'
82
+ version: '0.9'
83
83
  description:
84
84
  email:
85
85
  - timemaster.lpf@gmail.com
@@ -97,9 +97,13 @@ files:
97
97
  - bin/run
98
98
  - bin/setup
99
99
  - doc/ASSFile.html
100
+ - doc/ASSLine.html
100
101
  - doc/ASSStyle.html
102
+ - doc/ASSStyleParams.html
101
103
  - doc/ASSSubtitle.html
102
104
  - doc/Application.html
105
+ - doc/VTTFile.html
106
+ - doc/VTTLine.html
103
107
  - doc/VTTSubtitle.html
104
108
  - doc/Vtt2ass.html
105
109
  - doc/Vtt2ass/Error.html