md2slides 0.0.1 → 0.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f4a24667a8575a6e6cde9c235ef8647891bab980c81f17a346d3b8e292fce32d
4
- data.tar.gz: 5b26d1ce769583990de6ede00e0647ae2fea46e4f352a352e2db740ef14964c6
3
+ metadata.gz: b7ead7e0a1d48738b1f88a039ec73924afcab9eb35ea0a3bf15f6933d655690e
4
+ data.tar.gz: dfe7efa2cc63e30e8c71dc15c74b784725e812fed5dd619034393f4dd97bc772
5
5
  SHA512:
6
- metadata.gz: 4dbe7420d2a68f51fb381674e228e7c99cc7c1afbd5aba195355c93a50031c31f8ccdb443eb21d817892c9800e916a3198fd29a36855db0e8f46866da3263ac7
7
- data.tar.gz: 97390985806cf9a63ac0543ce8e5f88362b48138fc3ffe26b819ff7b758dc49a2dfcfadb455995ac6ec1ef54b271c2b73303d898a38af1b42fe869bff235e572
6
+ metadata.gz: 33410bc7876fcb1b24f24628d73a66a3d5314cb34b6a9460301b68c95fc22e5e2ce6677559f66eebff3df6d4742f148ab91007dfe63de4f56e08b2009c780050
7
+ data.tar.gz: bbed92243410bd696a193a4859e9076590690946662b29c792ef6bec9b5c33e68adc8fd5c760b0490019cc2a17226b0911ba2bc96a06811f0447d287c41abb7c
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ #/doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+
13
+ # vi file.
14
+ *.swp
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
6
+
7
+ # Specify your gem's dependencies in md2slides.gemspec
8
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ BSD 2-Clause License
2
+
3
+ Copyright (c) 2025, Motoyuki OHMORI <ohmori@tottori-u.ac.jp>
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,91 @@
1
+ # md2slides
2
+ *md2slides* generates a Google presentation from a markdown file.
3
+ A video file of a presentation will be also generated, and it may contains narration if supplied.
4
+ Narration can be given as notes in slides, and the audio will be generated using Google text-to-speech API and ffmpeg.
5
+
6
+ ## Quick start
7
+ 1. Generate your Google API credentials and copy it to credentails.json:
8
+ ```
9
+ % mkdir ~/.config/gcloud
10
+ % cat >> ~/.config/gcloud/credentials.json
11
+ {
12
+ "type": "service_account",
13
+ "project_id": "project-id",
14
+ "private_key_id": "private-key-ID',
15
+ "private_key": "-----BEGIN PRIVATE KEY-----\nhogehoge\n-----END PRIVATE KEY-----\n",
16
+ "client_email": "hogehoge@hogehoge.iam.gserviceaccount.com",
17
+ "client_id": "00000000000000000000",
18
+ "auth_uri": "https://accounts.google.com/o/oauth2/auth",
19
+ "token_uri": "https://oauth2.googleapis.com/token",
20
+ "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
21
+ "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/CLIENT.iam.gserviceaccount.com"
22
+ }
23
+ ^D (this means CTRL + D)
24
+ ```
25
+ 2. install ffmpeg if necessary (if producing video file).
26
+
27
+ 3. install necessary gems.
28
+ ```
29
+ % bundle install --path vendor/bundle
30
+ ```
31
+
32
+ 4. create an empty Google slide.
33
+
34
+ 5. write a markdown file.
35
+ ```
36
+ cat >> doc/sample.md
37
+ ---
38
+ title: hogehoge
39
+ url: <Google presentation URL>
40
+ ---
41
+ # title of the first title page
42
+ ## sub title or author's name(s)
43
+ <!--
44
+ narration text...
45
+ -->
46
+ ---
47
+ # title of the page
48
+ - hogehoge
49
+ ...
50
+ <!--
51
+ narration text...
52
+ -->
53
+ ^D (this means CTRL + D)
54
+ ```
55
+
56
+ 6. execute.
57
+ ```
58
+ bundle exec bin/md2slides doc/sample.md
59
+ ```
60
+
61
+ 7. the Google presentation is updated, and the video is stored in the current directory.
62
+
63
+ ## Installation
64
+
65
+ Add this line to your application's Gemfile:
66
+
67
+ ```ruby
68
+ gem 'md2slides'
69
+ ```
70
+
71
+ And then execute:
72
+
73
+ $ bundle
74
+
75
+ Or install it yourself as:
76
+
77
+ $ gem install md2slides
78
+
79
+ ## Usage
80
+
81
+ TODO: Write usage instructions here
82
+
83
+ ## Development
84
+
85
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
86
+
87
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
88
+
89
+ ## Contributing
90
+
91
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ohmori7/md2slides.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/TODO.md ADDED
@@ -0,0 +1,25 @@
1
+ # TODO
2
+ - abstraction of presentation elements
3
+ - PDF output
4
+ - character emphasis
5
+ - indentation
6
+ - itemization
7
+ - enumeration
8
+ - theme
9
+ - page number
10
+ - multi column
11
+ - image
12
+ - table
13
+ - other floating object
14
+ - generate a markdown file from an existing presentation file
15
+ - incremental updates
16
+ - other a presentation format such as Microsoft PowerPoint
17
+ - move to google new API:
18
+ *******************************************************************************
19
+ The google-gax gem is officially end-of-life and will not be updated further.
20
+
21
+ If your app uses the google-gax gem, it likely is using obsolete versions of
22
+ some Google Cloud client library (google-cloud-*) gem that depends on it. We
23
+ recommend updating any such libraries that depend on google-gax. Modern Google
24
+ Cloud client libraries will depend on the gapic-common gem instead.
25
+ *******************************************************************************
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "md2slides"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/exe/text2mp3 ADDED
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ # Copyright (c) 2025 Motoyuki OHMORI All rights reserved.
5
+
6
+ $:.unshift File.join(File.dirname(File.realpath(__FILE__)), '..', 'lib')
7
+
8
+ require 'presentation'
9
+
10
+ def usage(errmsg = nil)
11
+ puts "ERROR: #{errmsg}" if errmsg
12
+ puts <<~EOF
13
+ Usage:
14
+ #{$progname} [-f] <file>
15
+ #{$progname} -h
16
+
17
+ Description:
18
+ create a voice from a text using Google Text-To-Speech API.
19
+
20
+ Argument:
21
+ -h: output this message.
22
+
23
+ BUGS:
24
+ only .txt is allowed for an input file for now.
25
+
26
+ EOF
27
+ exit 1
28
+ end
29
+
30
+ v = ARGV.shift
31
+ case v
32
+ when '-h'
33
+ usage
34
+ when nil
35
+ usage
36
+ end
37
+ ifile = v
38
+ filename = Presentation::text_to_speech(File.read(ifile), ifile)
39
+ puts "save to #{filename}"
@@ -1,4 +1,7 @@
1
1
  class Presentation
2
+ # XXX: Google Text to Speech produces at this rate...
3
+ AUDIO_RATE = 24000
4
+
2
5
  def generate_audio0(i, slide, dir)
3
6
  print "slide \##{i + 1}: generating audio... "
4
7
  notes = get_slide_note(slide)
@@ -13,14 +16,13 @@ class Presentation
13
16
  #
14
17
  heading_silence = 2
15
18
  trailing_silence = 1
16
- audiorate = 24000
17
19
  cmd = <<~CMD
18
20
  ffmpeg -hide_banner -y \
19
21
  -f lavfi -t #{heading_silence} \
20
- -i anullsrc=r=#{audiorate}:cl=mono \
22
+ -i anullsrc=r=#{AUDIO_RATE}:cl=mono \
21
23
  -i #{opath} \
22
24
  -f lavfi -t #{trailing_silence} \
23
- -i anullsrc=r=#{audiorate}:cl=mono \
25
+ -i anullsrc=r=#{AUDIO_RATE}:cl=mono \
24
26
  -filter_complex "[0:a][1:a][2:a]concat=n=3:v=0:a=1[out]" \
25
27
  -map "[out]" \
26
28
  -c:a aac -b:a 64k #{path}
@@ -356,9 +356,7 @@ class Presentation
356
356
  end
357
357
 
358
358
  def __data_path(basedir)
359
- if basedir.nil?
360
- basedir = File.join(BASEDIR, 'data')
361
- end
359
+ basedir = '.' if basedir.nil?
362
360
  title, subtitle = get_title
363
361
  title = self.class.filename_sanitize(title)
364
362
  subtitle = self.class.filename_sanitize(subtitle)
@@ -0,0 +1,3 @@
1
+ module Md2slides
2
+ VERSION = "0.0.3"
3
+ end
@@ -6,9 +6,6 @@ class Presentation
6
6
  audio = __data_slide_path(i, '.m4a', dir)
7
7
  video = __data_slide_path(i, '.mp4', dir)
8
8
 
9
- # XXX: Google Text to Speech produces this...
10
- audiorate = 24000
11
-
12
9
  if File.exists?(audio)
13
10
  audioin = "-i \"#{audio}\""
14
11
  timeopt = '-shortest'
@@ -21,7 +18,7 @@ class Presentation
21
18
  -framerate 15 -loop 1 -i "#{img}" \
22
19
  #{audioin} -map 0:v:0 -map 1:a:0 \
23
20
  -c:v libx264 -tune stillimage \
24
- -c:a aac -ar #{audiorate} -ac 1 \
21
+ -c:a aac -ar #{AUDIO_RATE} -ac 1 \
25
22
  -pix_fmt yuv420p #{timeopt} "#{video}"
26
23
  CMD
27
24
  msg, errmsg, status = Open3.capture3(cmd)
@@ -39,13 +36,13 @@ class Presentation
39
36
  end
40
37
 
41
38
  print "concatenate video files..."
42
- videolist = File.join(dir, 'video-list.txt')
43
- File.open(videolist, 'w') do |f|
39
+ videolist = 'video-list.txt'
40
+ File.open(File.join(dir, videolist), 'w') do |f|
44
41
  @presentation.slides.each_with_index do |slide, i|
45
42
  f.puts("file #{__data_slide_path(i, '.mp4')}")
46
43
  end
47
44
  end
48
- video = File.join(dir, 'video.mp4')
45
+ video = 'video.mp4'
49
46
  cmd = <<~CMD
50
47
  cd "#{dir}" && \
51
48
  ffmpeg -hide_banner -y -f concat -safe 0 \
data/lib/md2slides.rb CHANGED
@@ -1,7 +1,15 @@
1
1
  $:.unshift File.dirname(File.dirname(File.realpath(__FILE__)))
2
- require 'config/config'
3
- require 'md2slides/md'
4
- require 'md2slides/presentation'
5
- require 'md2slides/text_to_speech'
6
- require 'md2slides/audio'
7
- require 'md2slides/video'
2
+
3
+ module Md2slides
4
+ class Error < StandardError; end
5
+
6
+ # XXX: platform independent path configuration...
7
+ ENV['GOOGLE_APPLICATION_CREDENTIALS'] ||= File.join(Dir.home, ".config/gcloud/credentials.json")
8
+
9
+ require 'md2slides/md'
10
+ require 'md2slides/presentation'
11
+ require 'md2slides/text_to_speech'
12
+ require 'md2slides/audio'
13
+ require 'md2slides/video'
14
+ require "md2slides/version"
15
+ end
data/md2slides.gemspec ADDED
@@ -0,0 +1,47 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "md2slides/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "md2slides"
8
+ spec.version = Md2slides::VERSION
9
+ spec.authors = ["Motoyuki OHMORI"]
10
+ spec.email = ["ohmori@tottori-u.ac.jp"]
11
+
12
+ spec.summary = %q{Markdown to presentation slides in ruby.}
13
+ spec.description = %q{Generate Google slides and its video file from a markdown file.}
14
+ spec.homepage = "https://github.com/ohmori7/md2slides"
15
+
16
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
18
+ if spec.respond_to?(:metadata)
19
+ # spec.metadata["allowed_push_host"] = spec.homepage
20
+
21
+ spec.metadata["homepage_uri"] = spec.homepage
22
+ spec.metadata["source_code_uri"] = spec.homepage
23
+ spec.metadata["changelog_uri"] = spec.homepage
24
+ else
25
+ raise "RubyGems 2.0 or newer is required to protect against " \
26
+ "public gem pushes."
27
+ end
28
+
29
+ # Specify which files should be added to the gem when it is released.
30
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
31
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
32
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
33
+ end
34
+ spec.bindir = "exe"
35
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
36
+ spec.require_paths = ["lib"]
37
+
38
+ spec.add_dependency "googleauth"
39
+ # spec.add_dependency "google-apis-people_v1"
40
+ spec.add_dependency "google-apis-slides_v1"
41
+ spec.add_dependency "google-apis-drive_v3"
42
+ spec.add_dependency "google-cloud-text_to_speech", "~>0.7.0"
43
+ spec.add_development_dependency "bundler", "~> 1.17"
44
+ spec.add_development_dependency "rake", "~> 10.0"
45
+ spec.add_development_dependency "rspec", "~> 3.0"
46
+ spec.license = "MIT"
47
+ end
@@ -0,0 +1,2 @@
1
+ *
2
+ !.gitignore
metadata CHANGED
@@ -1,33 +1,149 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: md2slides
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Motoyuki OHMORI
8
8
  autorequire:
9
- bindir: bin
9
+ bindir: exe
10
10
  cert_chain: []
11
11
  date: 2025-04-29 00:00:00.000000000 Z
12
- dependencies: []
13
- description: Generate Google slides and its video file from a markdown file
14
- email: ohmori@tottori-u.ac.jp
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: googleauth
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: google-apis-slides_v1
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: google-apis-drive_v3
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: google-cloud-text_to_speech
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.7.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.7.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.17'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.17'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '10.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '10.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '3.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '3.0'
111
+ description: Generate Google slides and its video file from a markdown file.
112
+ email:
113
+ - ohmori@tottori-u.ac.jp
15
114
  executables:
16
115
  - md2slides
116
+ - text2mp3
17
117
  extensions: []
18
118
  extra_rdoc_files: []
19
119
  files:
20
- - bin/md2slides
120
+ - ".gitignore"
121
+ - ".rspec"
122
+ - Gemfile
123
+ - LICENSE
124
+ - README.md
125
+ - Rakefile
126
+ - TODO.md
127
+ - bin/console
128
+ - bin/setup
129
+ - exe/md2slides
130
+ - exe/text2mp3
21
131
  - lib/md2slides.rb
22
132
  - lib/md2slides/audio.rb
23
133
  - lib/md2slides/md.rb
24
134
  - lib/md2slides/presentation.rb
25
135
  - lib/md2slides/text_to_speech.rb
136
+ - lib/md2slides/version.rb
26
137
  - lib/md2slides/video.rb
138
+ - md2slides.gemspec
139
+ - vendor/bundle/.gitignore
27
140
  homepage: https://github.com/ohmori7/md2slides
28
141
  licenses:
29
142
  - MIT
30
- metadata: {}
143
+ metadata:
144
+ homepage_uri: https://github.com/ohmori7/md2slides
145
+ source_code_uri: https://github.com/ohmori7/md2slides
146
+ changelog_uri: https://github.com/ohmori7/md2slides
31
147
  post_install_message:
32
148
  rdoc_options: []
33
149
  require_paths:
@@ -46,5 +162,5 @@ requirements: []
46
162
  rubygems_version: 3.0.3.1
47
163
  signing_key:
48
164
  specification_version: 4
49
- summary: Markdown to presentation slides in ruby
165
+ summary: Markdown to presentation slides in ruby.
50
166
  test_files: []
File without changes