middleman-medium_export 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +77 -0
- data/lib/middleman-medium_export.rb +8 -0
- data/lib/middleman-medium_export/api_client.rb +53 -0
- data/lib/middleman-medium_export/articles_filter.rb +36 -0
- data/lib/middleman-medium_export/commands/export.rb +74 -0
- data/lib/middleman-medium_export/content.rb +58 -0
- data/lib/middleman-medium_export/extension.rb +66 -0
- data/lib/middleman-medium_export/publisher.rb +30 -0
- data/lib/middleman-medium_export/template.rb +9 -0
- metadata +140 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 70a0f8d944340107139756124aa63973a3f71c686fcee927ea63a830e8971f22
|
4
|
+
data.tar.gz: 8cca4d27765a84ffaedb871012d3f46fe1b2ec33f4d8874155a6c4a593829c17
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c6884c14ae7550558aa91a0ce8d80d548f1a37c5305b6d291ccae6910cc79a7ece792218b36cdd3a730d1f419163edf0f9743a3930997a95134947c1c6b64570
|
7
|
+
data.tar.gz: 7178bd55aab8c1524da4464caf0a91189f3a50eaa9044b0a922050536959afeafe2e1a30757850199ee7c53605c48b3ab16cac75bc136005eb762e1767382a8d
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 John Nunemaker
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
# Middleman Medium Export
|
2
|
+
|
3
|
+
A Middleman extension that adds a cli command to export your articles to medium
|
4
|
+
|
5
|
+
# Getting Started
|
6
|
+
|
7
|
+
Add the gem to your gemfile
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem "middleman-medium_export"
|
11
|
+
```
|
12
|
+
|
13
|
+
Activate it in your `config.rb`
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
activate :medium_export do |export|
|
17
|
+
export.api_token = 'your_api_token'
|
18
|
+
|
19
|
+
# export.template_path = 'path_to_template'
|
20
|
+
# export.template_position = :top
|
21
|
+
# export.publish_status = :draft
|
22
|
+
end
|
23
|
+
```
|
24
|
+
|
25
|
+
## Options
|
26
|
+
|
27
|
+
Extension provides several options
|
28
|
+
|
29
|
+
`api_token` - required, self issued api token to post your articles
|
30
|
+
|
31
|
+
`template_path` - optinal, path to partial to add to your article
|
32
|
+
`template_position` - optional. Position of your template. Possible values are: `:top` and `:bottom`. Default is `:bottom`
|
33
|
+
`publish_status` - optional. Status of your articles, when they are exported. Possible values are: `public`, `draft`, or `unlisted`. Default is `:draft`
|
34
|
+
|
35
|
+
## Export
|
36
|
+
|
37
|
+
### Interactivly
|
38
|
+
|
39
|
+
To chose article to export interactivlt
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
be middleman medium_export -m interactive
|
43
|
+
```
|
44
|
+
|
45
|
+
### Only last article
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
be middleman medium_export
|
49
|
+
```
|
50
|
+
|
51
|
+
or
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
be middleman medium_export -m last
|
55
|
+
```
|
56
|
+
|
57
|
+
### All articles
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
be middleman medium_export -m all
|
61
|
+
```
|
62
|
+
|
63
|
+
## Obtaining Api Token
|
64
|
+
|
65
|
+
You used to be able to create an `api_token` yourself, but due to increased spam activity from API, this feature is now restricted. You need to email support with request for an API Token. It usually takes from a couple of hours to a day. Visit official [documentaion](https://github.com/Medium/medium-api-docs#22-self-issued-access-tokens) for more info.
|
66
|
+
|
67
|
+
# Contribution
|
68
|
+
|
69
|
+
Pull requests and issues are very welcome
|
70
|
+
|
71
|
+
To create a pull request
|
72
|
+
|
73
|
+
* Clone repo
|
74
|
+
* Run tests to see, that all is fine `be rake test`
|
75
|
+
* Implement feature
|
76
|
+
* Add tests
|
77
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
|
3
|
+
class MediumExport::ApiClient
|
4
|
+
include HTTParty
|
5
|
+
|
6
|
+
attr_reader :auth, :publish_status
|
7
|
+
|
8
|
+
base_uri 'https://api.medium.com/v1/'
|
9
|
+
|
10
|
+
headers 'Content-Type': 'application/json'
|
11
|
+
headers 'Accept': 'application/json'
|
12
|
+
|
13
|
+
# raise_on (400..599).to_a
|
14
|
+
|
15
|
+
def initialize(api_token:, publish_status:)
|
16
|
+
@auth = { Authorization: "Bearer #{api_token}" }
|
17
|
+
@publish_status = publish_status
|
18
|
+
end
|
19
|
+
|
20
|
+
def publish(content:, title:, tags:)
|
21
|
+
response = self.class.post(
|
22
|
+
"/users/#{id}/posts",
|
23
|
+
headers: auth,
|
24
|
+
body: {
|
25
|
+
"title": title,
|
26
|
+
"contentFormat": "html",
|
27
|
+
"content": content,
|
28
|
+
"tags": tags,
|
29
|
+
"publishStatus": publish_status
|
30
|
+
}.to_json
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
def upload_image(image:)
|
35
|
+
response = self.class.post(
|
36
|
+
"https://api.medium.com/v1/images",
|
37
|
+
headers: auth,
|
38
|
+
body: {
|
39
|
+
"image": image
|
40
|
+
}
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
def me
|
45
|
+
self.class.get('/me', headers: auth)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def id
|
51
|
+
@id ||= me['data']['id']
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class MediumExport::ArticlesFilter
|
2
|
+
attr_reader :articles, :shell
|
3
|
+
|
4
|
+
def initialize(articles:, shell:)
|
5
|
+
@articles = articles
|
6
|
+
@shell = shell
|
7
|
+
end
|
8
|
+
|
9
|
+
def last
|
10
|
+
[articles.first]
|
11
|
+
end
|
12
|
+
|
13
|
+
def all
|
14
|
+
articles
|
15
|
+
end
|
16
|
+
|
17
|
+
def interactive
|
18
|
+
articles.each_with_object([]) do |article, acc|
|
19
|
+
case ask_to_include(article.title)
|
20
|
+
when 'Y' then acc.push(article)
|
21
|
+
when 'S' then acc.push(article) and break(acc)
|
22
|
+
when 'Q' then break(acc)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def ask_to_include(title)
|
30
|
+
shell.say(%Q(Do you want to publish "#{title}"\n).freeze)
|
31
|
+
shell.say(" Y - yes and continue\n S - yes and quit".freeze, :green)
|
32
|
+
shell.say(" N - no and continue\n Q - no and quit\n".freeze, :red)
|
33
|
+
|
34
|
+
shell.ask("\n ", :magenta, limited_to: %w(Y S N Q).freeze)
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'middleman-core/cli'
|
2
|
+
require 'middleman-blog/uri_templates'
|
3
|
+
require 'middleman-medium_export/articles_filter'
|
4
|
+
require 'middleman-medium_export/content'
|
5
|
+
require 'middleman-medium_export/publisher'
|
6
|
+
|
7
|
+
module Middleman
|
8
|
+
|
9
|
+
module Cli
|
10
|
+
|
11
|
+
##
|
12
|
+
# This class provides an "medium_export" command for the middleman CLI.
|
13
|
+
#
|
14
|
+
# @usage bundle exec middleman medium_export
|
15
|
+
# @usage bundle exec middleman medium_export --help
|
16
|
+
# @usage bundle exec middleman medium_export --mode last
|
17
|
+
# @usage bundle exec middleman medium_export --mode interactive
|
18
|
+
#
|
19
|
+
##
|
20
|
+
class Export < ::Thor::Group
|
21
|
+
include Thor::Actions
|
22
|
+
include Blog::UriTemplates
|
23
|
+
|
24
|
+
check_unknown_options!
|
25
|
+
|
26
|
+
class_option "blog",
|
27
|
+
aliases: "-b",
|
28
|
+
desc: "The name of the blog to create the post inside (for multi-blog apps, defaults to the only blog in single-blog apps)"
|
29
|
+
|
30
|
+
class_option "mode",
|
31
|
+
aliases: "-m",
|
32
|
+
enum: %w[last all interactive],
|
33
|
+
default: 'last',
|
34
|
+
desc: "Chose which articles should be published"
|
35
|
+
|
36
|
+
|
37
|
+
def medium_export
|
38
|
+
articles = blog.data.articles.sort_by { |a| -a.date.to_i }
|
39
|
+
|
40
|
+
filtered_articles = MediumExport::ArticlesFilter.
|
41
|
+
new(articles: articles, shell: shell).
|
42
|
+
public_send(options.mode)
|
43
|
+
|
44
|
+
content = filtered_articles.map do |article|
|
45
|
+
MediumExport::Content.new(article: article, template: export_extension.template)
|
46
|
+
end
|
47
|
+
|
48
|
+
MediumExport::Publisher.new(
|
49
|
+
api_client: export_extension.api_client, content: content, shell: shell).call
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def export_extension
|
55
|
+
@export_extension ||= app.extensions[:medium_export]
|
56
|
+
end
|
57
|
+
|
58
|
+
def app
|
59
|
+
@app ||= ::Middleman::Application.new
|
60
|
+
end
|
61
|
+
|
62
|
+
def blog
|
63
|
+
@blog ||= if options[:blog]
|
64
|
+
app.extensions[:blog].find { | k, v | v.options[:name] == options[ :blog ] }.last
|
65
|
+
else
|
66
|
+
app.extensions[:blog].values.first
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Add to CLI
|
71
|
+
Base.register(self, 'medium_export', 'medium_export [options]', 'Export one or more articles to middleman')
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
class MediumExport::Content
|
4
|
+
Image = Struct.new(:src, :location)
|
5
|
+
|
6
|
+
attr_reader :article, :template
|
7
|
+
|
8
|
+
def initialize(article:, template: nil)
|
9
|
+
@article = article
|
10
|
+
@template = template
|
11
|
+
end
|
12
|
+
|
13
|
+
def html
|
14
|
+
@content ||= begin
|
15
|
+
template ? body_with_template : article.body
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def markdown
|
20
|
+
@markdown ||= File.read(article.source_file)
|
21
|
+
end
|
22
|
+
|
23
|
+
def title
|
24
|
+
article.title
|
25
|
+
end
|
26
|
+
|
27
|
+
def tags
|
28
|
+
article.tags
|
29
|
+
end
|
30
|
+
|
31
|
+
def local_images
|
32
|
+
@images ||= Nokogiri::HTML(html).search('img').map do |img|
|
33
|
+
src = img.attributes['src'].value
|
34
|
+
next if src.start_with?('http')
|
35
|
+
|
36
|
+
Image.new(src, File.join(source_dir, src))
|
37
|
+
end.compact
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def body_with_template
|
43
|
+
template_html = template_context.render(nil, template.path, { locals: {}})
|
44
|
+
template.position == :top ? "#{template_html}#{article.body}" : "#{article.body}#{template_html}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def source_dir
|
48
|
+
@source_dir ||= app.source_dir
|
49
|
+
end
|
50
|
+
|
51
|
+
def template_context
|
52
|
+
@template_context ||= app.generic_template_context
|
53
|
+
end
|
54
|
+
|
55
|
+
def app
|
56
|
+
@app ||= article.blog_data.controller.app
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# Require core library
|
2
|
+
require 'middleman-core'
|
3
|
+
|
4
|
+
# Extension namespace
|
5
|
+
class MediumExport < ::Middleman::Extension
|
6
|
+
require 'middleman-medium_export/api_client'
|
7
|
+
require 'middleman-medium_export/template'
|
8
|
+
|
9
|
+
ApiTokenMissing = Class.new(ArgumentError)
|
10
|
+
InvalidTemplatePosition = Class.new(ArgumentError)
|
11
|
+
InvalidPublishStatus = Class.new(ArgumentError)
|
12
|
+
|
13
|
+
TEMPLATES_POSSITIONS = %w[bottom top].freeze
|
14
|
+
PUBLISH_STATUSES = %i[public draft unlisted].freeze
|
15
|
+
|
16
|
+
option :api_token, nil, 'Medium API Token'
|
17
|
+
option :template_path, nil, 'HTML template to append to the end of each article'
|
18
|
+
option :template_position, :bottom
|
19
|
+
option :publish_status, :draft
|
20
|
+
option :tags_field, :tags
|
21
|
+
|
22
|
+
def initialize(app, options_hash={}, &block)
|
23
|
+
super
|
24
|
+
|
25
|
+
check_api_token!
|
26
|
+
check_template_positions!
|
27
|
+
check_publish_statuses!
|
28
|
+
end
|
29
|
+
|
30
|
+
def api_client
|
31
|
+
@api_client ||= ApiClient.new(options.to_h.slice(:api_token, :publish_status))
|
32
|
+
end
|
33
|
+
|
34
|
+
def template
|
35
|
+
return unless options.template_path
|
36
|
+
|
37
|
+
Template.new(options.to_h.slice(:template_path, :template_position))
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def check_api_token!
|
43
|
+
return unless options.api_token.to_s.empty?
|
44
|
+
|
45
|
+
error_msg = "Please, provide an api_token option. To obtain api_token refer to\n" \
|
46
|
+
"https://help.medium.com/hc/en-us/articles/213480228-Get-integration-token\n\n"
|
47
|
+
raise ApiTokenMissing, error_msg
|
48
|
+
end
|
49
|
+
|
50
|
+
def check_template_positions!
|
51
|
+
position = options.template_position.to_s
|
52
|
+
return if position.empty? || TEMPLATES_POSSITIONS.include?(position)
|
53
|
+
|
54
|
+
error_msg = "Invalid template_position: #{options.template_position}.\n" \
|
55
|
+
"Possible template positions are: #{TEMPLATES_POSSITIONS.join(", ")}\n\n"
|
56
|
+
raise InvalidTemplatePosition, error_msg
|
57
|
+
end
|
58
|
+
|
59
|
+
def check_publish_statuses!
|
60
|
+
return if PUBLISH_STATUSES.include?(options.publish_status.to_sym)
|
61
|
+
|
62
|
+
error_msg = "Invalid publish_status: #{options.publish_status}.\n" \
|
63
|
+
"Possible publish statuses are: #{PUBLISH_STATUSES.join(", ")}\n\n"
|
64
|
+
raise InvalidPublishStatus, error_msg
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class MediumExport::Publisher
|
2
|
+
attr_reader :content, :shell, :api_client
|
3
|
+
|
4
|
+
def initialize(content:, shell:, api_client:)
|
5
|
+
@content = content
|
6
|
+
@shell = shell
|
7
|
+
@api_client = api_client
|
8
|
+
end
|
9
|
+
|
10
|
+
def call
|
11
|
+
shell.say("Preparing to publish #{content.size} articles") if content.size > 1
|
12
|
+
|
13
|
+
content.each do |article|
|
14
|
+
publish(article)
|
15
|
+
shell.say(%Q(Published: "#{article.title}"), :green)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def publish(article)
|
22
|
+
updated_html = article.local_images.inject(article.html) do |html, image|
|
23
|
+
response = api_client.upload_image(image: File.open(image.location))
|
24
|
+
url = response['data']['url'] # it may contain errors {"errors"=>[{"message"=>"Token was invalid.", "code"=>6003}]}
|
25
|
+
html.gsub(image.src, url)
|
26
|
+
end
|
27
|
+
|
28
|
+
api_client.publish(content: updated_html, tags: article.tags, title: article.title)
|
29
|
+
end
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: middleman-medium_export
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- TheSmartnik
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-05-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: middleman-core
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.2.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 4.2.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: middleman-blog
|
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: nokogiri
|
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: httparty
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.16.3
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.16.3
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: middleman-cli
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: |
|
98
|
+
An extension to export your articles created with
|
99
|
+
middleman-blog to medium from a command line.
|
100
|
+
email:
|
101
|
+
- misharinn@gmail.com
|
102
|
+
executables: []
|
103
|
+
extensions: []
|
104
|
+
extra_rdoc_files: []
|
105
|
+
files:
|
106
|
+
- MIT-LICENSE
|
107
|
+
- README.md
|
108
|
+
- lib/middleman-medium_export.rb
|
109
|
+
- lib/middleman-medium_export/api_client.rb
|
110
|
+
- lib/middleman-medium_export/articles_filter.rb
|
111
|
+
- lib/middleman-medium_export/commands/export.rb
|
112
|
+
- lib/middleman-medium_export/content.rb
|
113
|
+
- lib/middleman-medium_export/extension.rb
|
114
|
+
- lib/middleman-medium_export/publisher.rb
|
115
|
+
- lib/middleman-medium_export/template.rb
|
116
|
+
homepage: https://github.com/TheSmartnik/middleman-medium_export
|
117
|
+
licenses:
|
118
|
+
- MIT
|
119
|
+
metadata: {}
|
120
|
+
post_install_message:
|
121
|
+
rdoc_options: []
|
122
|
+
require_paths:
|
123
|
+
- lib
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
requirements: []
|
135
|
+
rubyforge_project:
|
136
|
+
rubygems_version: 2.7.6
|
137
|
+
signing_key:
|
138
|
+
specification_version: 4
|
139
|
+
summary: A Middleman extension to export your blogposts to medium
|
140
|
+
test_files: []
|