jekyll-gemini 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 76da48d0eea156a0c2a54c82335d76b5c1e8c11428ab9ca3df8f98320de60e4f
4
+ data.tar.gz: 799dda937000ef8e682e622d27bdc7bc59b42ec540d63c2af416d3259c1a8200
5
+ SHA512:
6
+ metadata.gz: 3796c1f5d429dff9cb31e8f5f5f769ab05ce30dfe168c19c946017963d42f4741e25e3484cdf4a34924ed517d05118c432b55ebf2b3c880fa5943179ecb26249
7
+ data.tar.gz: 89bc9f0dbc170611ba8f2c00dc0f0b8b5c1597e6c1084dff5046d91a8b18832d38006d4b369cb210648e7dbcbc82df3ceff1eb86f1d7f924eddb2364ccaa4006
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ ruby RUBY_VERSION
6
+
7
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2021 Jeremy Wilkins
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.gmi ADDED
@@ -0,0 +1,88 @@
1
+ # Jekyll Gemini
2
+
3
+ Plugin for Jekyll to allow publishing to both the Web and Geminispace from a single set of sources.
4
+
5
+ This relies on the source files using Gemtext instead of Markdown, which are converted automatically via the Jekyll-Gemtext.
6
+
7
+ Any Gemtext files will be converted to HTML in _site via the usual jekyll build command.
8
+
9
+ A _capsule folder can also be generated by running jekyll gemini - only Static files and Gemtext source files are included - markdown Pages and Documents are ignored.
10
+
11
+ The built _capsule folder can then be uploaded to a Geminispace hosting service.
12
+
13
+ NOTE: This is the first release and very much still Alpha at the moment
14
+
15
+ ## Installation
16
+
17
+ Add the gem to your Gemfile
18
+
19
+ ```ruby
20
+ # Gemfile
21
+
22
+ gem 'jekyll-gemini'
23
+ ```
24
+
25
+ Then install the gems,
26
+
27
+ ```bash
28
+ bundle install
29
+ ```
30
+
31
+ ## Layouts
32
+
33
+ Next you need to add layouts for the Gemini capsule - these go in a _gemini_layouts folder, and need to be Gemtext equivalents of the HTML layouts you will already have, eg using liquid to embed content within the Gemtext layouts.
34
+
35
+ These use liquid tags the same as html layouts but are likely to be very simple, eg, _gemini_layouts/default.gmi might be -:
36
+
37
+ ```gemtext
38
+ # {{ site.title }}
39
+
40
+ {{ content }}
41
+ ```
42
+
43
+ ## Pages
44
+
45
+ Jekyll relies on HTML files with liquid tags embedded within to generate the index pages. There are two ways to extend this
46
+
47
+ ### Option 1 - use Gemtext for index pages
48
+
49
+ If your requirements are simple you may be able to convert your index.html to index.gmi and use the same page for both Website and Capsule
50
+
51
+ ### Option 2 - separate index pages for Website and Capsule
52
+
53
+ If you need to make fuller use of HTML features in your index.html, you can keep your existing index.html - this will be ignore when building the Geminispace capsule.
54
+
55
+ You will need to add an index.gmi, but mark this to target just the Capsule (otherwise you'll end up with both index.html and index.gmi included in your website)
56
+
57
+ ```gemtext
58
+ ---
59
+ layout: default
60
+ target: capsule
61
+ ---
62
+ {% for post in site.posts limit:1 %}
63
+ # {{ post.title }}
64
+ {{ post.date | date: "%b %-d, %Y" }}{% if post.author %} • {{ post.author }}{% endif %}{% if page.meta %} • {{ page.meta }}{% endif %}
65
+ {{ post.content }}
66
+ {% endfor %}
67
+ {% for post in site.posts offset:1 %}
68
+ => {{ post.url }} {{ post.title }}
69
+ ## {{ post.title }}
70
+ {{ post.date | date: "%b %-d, %Y" }}{% if post.author %} • {{ post.author }}{% endif %}{% if page.meta %} • {{ page.meta }}{% endif %}
71
+ {{ post.excerpt }}
72
+ => {{ post.url }} Read More
73
+ {% endfor %}
74
+ ```
75
+
76
+ ## Links
77
+
78
+ => https://gemini.circumlunar.space/docs/gemtext.gmi Gemtext docs
79
+ => https://gemini.circumlunar.space/ About Gemini
80
+
81
+ ## To do
82
+
83
+ 1. Add RSS/Atom generation - this seems common in Geminispace, currently generators are just disabled when building the Capsule
84
+ 2. Add specs
85
+
86
+ ## Problems
87
+
88
+ Please raise an issue on GitHub - https://github.com/jebw/jekyll-gemini/issues
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rubygems'
4
+ require 'bundler/gem_tasks'
5
+ require 'rspec/core/rake_task'
6
+ require 'yard'
7
+ require 'rubocop/rake_task'
8
+
9
+ RuboCop::RakeTask.new
10
+
11
+ desc 'Run all examples'
12
+ RSpec::Core::RakeTask.new(:spec) do |t|
13
+ t.rspec_opts = %w[--color]
14
+ end
15
+
16
+ YARD::Rake::YardocTask.new do |t|
17
+ t.files = ['lib/**/*.rb']
18
+ end
19
+
20
+ task default: :spec
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = 'jekyll-gemini'
8
+ gem.version = '0.1.0'
9
+ gem.summary = 'Jekyll plugin to publish to Geminispace'
10
+ gem.description = <<~DESCRIPTION
11
+ Plugin for Jekyll to publish your Jekyll site to both the Web and
12
+ Geminispace from the same set of source Pages and Posts
13
+ DESCRIPTION
14
+ gem.authors = ['Jeremy Wilkins']
15
+ gem.email = ['jeb@jdwilkins.co.uk']
16
+ gem.homepage = 'https://github.com/jebw/jekyll-gemini'
17
+ gem.license = 'MIT'
18
+ gem.metadata = {
19
+ 'rubygems_mfa_required' => 'true'
20
+ }
21
+
22
+ gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR).reject do |f|
23
+ f.match %r{^(\.|spec)}
24
+ end
25
+ gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
26
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
27
+ gem.require_paths = %w[lib]
28
+ gem.required_ruby_version = '>= 2.5.0'
29
+
30
+ gem.add_dependency 'jekyll', '>= 3.7', '< 5.0'
31
+ gem.add_dependency 'jekyll-gemtext', '~> 0.1'
32
+
33
+ gem.add_development_dependency 'bundler', '~> 2.2'
34
+ gem.add_development_dependency 'byebug', '~> 11.1'
35
+ gem.add_development_dependency 'rake', '~> 13.0'
36
+ gem.add_development_dependency 'rspec', '~> 3.10'
37
+ gem.add_development_dependency 'rubocop', '~> 1.23'
38
+ gem.add_development_dependency 'rubocop-rake', '~> 0.6'
39
+ gem.add_development_dependency 'rubocop-rspec', '~> 2.6'
40
+ gem.add_development_dependency 'simplecov', '~> 0.21'
41
+ gem.add_development_dependency 'yard', '~> 0.9.26'
42
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jekyll_gemini'
4
+ require 'jekyll_gemini/command'
5
+ require 'jekyll_gemini/configuration'
6
+ require 'jekyll_gemini/capsule'
7
+ require 'jekyll_gemini/converter'
8
+ require 'jekyll_gemini/fixes'
9
+ require 'jekyll_gemini/publisher'
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JekyllGemini
4
+ class Capsule < Jekyll::Site
5
+ def setup
6
+ super
7
+
8
+ self.converters = [Converter.new(config)]
9
+ self.generators = []
10
+ end
11
+
12
+ def publisher
13
+ @publisher ||= Publisher.new(self)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JekyllGemini
4
+ class Command < Jekyll::Command
5
+ class << self
6
+ def init_with_program(prog)
7
+ prog.command(:gemini) do |c|
8
+ c.syntax "gemini [options]"
9
+ c.description 'Build the Gemini capsule'
10
+
11
+ add_build_options(c)
12
+
13
+ c.action do |_, options|
14
+ options["serving"] = false
15
+ process_with_graceful_fail(c, options, self)
16
+ end
17
+ end
18
+
19
+ def process(options)
20
+ # Adjust verbosity quickly
21
+ Jekyll.logger.adjust_verbosity(options)
22
+
23
+ options = configuration_from_options(options)
24
+ capsule = Capsule.new(options)
25
+
26
+ if options.fetch("skip_initial_build", false)
27
+ Jekyll.logger.warn "Build Warning:", "Skipping the initial build." \
28
+ " This may result in an out-of-date site."
29
+ else
30
+ build(capsule, options)
31
+ end
32
+ end
33
+
34
+ def build(site, options)
35
+ t = Time.now
36
+ source = File.expand_path(options["source"])
37
+ destination = File.expand_path(options["destination"])
38
+ incremental = options["incremental"]
39
+ Jekyll.logger.info "Source:", source
40
+ Jekyll.logger.info "Destination:", destination
41
+ Jekyll.logger.info "Incremental build:",
42
+ (incremental ? "enabled" : "disabled. Enable with --incremental")
43
+ Jekyll.logger.info "Generating..."
44
+ process_site(site)
45
+ Jekyll.logger.info "", "done in #{(Time.now - t).round(3)} seconds."
46
+ end
47
+
48
+ def configuration_from_options(options)
49
+ return options if options.is_a?(Jekyll::Configuration)
50
+
51
+ Configuration.build(options)
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JekyllGemini
4
+ class Configuration
5
+ CAPSULE_DEFAULTS = {
6
+ 'layouts_dir' => '_gemini_layouts',
7
+ 'destination' => File.join(Dir.pwd, '_capsule'),
8
+ 'theme' => nil
9
+ }.freeze
10
+
11
+ CAPSULE_DEFAULT_EXCLUDES = %w[css js fonts].freeze
12
+
13
+ class << self
14
+ def build(override)
15
+ Jekyll.configuration(override)
16
+ .tap(&method(:add_capsule_defaults))
17
+ .tap(&method(:add_capsule_specific_keys))
18
+ .tap(&method(:add_capsule_excludes))
19
+ end
20
+
21
+ private
22
+
23
+ def add_capsule_defaults(config)
24
+ config.merge!(CAPSULE_DEFAULTS)
25
+ end
26
+
27
+ def add_capsule_specific_keys(config)
28
+ capsule_keys = (config['capsule'] || {}).dup
29
+ capsule_keys.delete('exclude')
30
+
31
+ config.merge!(capsule_keys)
32
+ end
33
+
34
+ def add_capsule_excludes(config)
35
+ excludes = (config['capsule'] || {})['exclude']
36
+ excludes ||= CAPSULE_DEFAULT_EXCLUDES
37
+
38
+ config['exclude'] ||= []
39
+ config['exclude'].concat(excludes).uniq!
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JekyllGemini
4
+ class Converter
5
+ GEMTEXT_EXT = %w[.gmi .gmni .gemini].freeze
6
+
7
+ def initialize(_config); end
8
+
9
+ def matches(ext)
10
+ GEMTEXT_EXT.include?(ext)
11
+ end
12
+
13
+ def output_ext(_ext)
14
+ '.gmi'
15
+ end
16
+
17
+ # Passthrough without conversion
18
+ def convert(content)
19
+ content
20
+ end
21
+
22
+ def highlighter_prefix; end
23
+ def highlighter_suffix; end
24
+ end
25
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JekyllGemini
4
+ module Fixes
5
+ module Destination
6
+ def destination(*_args)
7
+ super.gsub(%r{/index.html\z}, "/index#{output_ext}")
8
+ end
9
+ end
10
+
11
+ module Publisher
12
+ def publisher
13
+ @publisher ||= ::JekyllGemini::Publisher.new(self)
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ Jekyll::Document.prepend JekyllGemini::Fixes::Destination
20
+ Jekyll::Site.prepend JekyllGemini::Fixes::Publisher
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JekyllGemini
4
+ class Publisher < ::Jekyll::Publisher
5
+ def publish?(item)
6
+ super && compatible_with_site?(item) && targetted_at_site?(item)
7
+ end
8
+
9
+ private
10
+
11
+ def compatible_with_site?(item)
12
+ @site.is_a?(Capsule) ? gemtext?(item) : true
13
+ end
14
+
15
+ def gemtext?(item)
16
+ Converter::GEMTEXT_EXT.include?(item.extname)
17
+ end
18
+
19
+ def targetted_at_site?(item)
20
+ case item.data.fetch('target', nil)
21
+ when 'capsule' then @site.is_a?(Capsule)
22
+ when 'site' then !@site.is_a?(Capsule)
23
+ else true
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jekyll-gemtext'
4
+ require 'jekyll_gemini/command'
5
+ require 'jekyll_gemini/configuration'
6
+ require 'jekyll_gemini/capsule'
7
+ require 'jekyll_gemini/converter'
8
+ require 'jekyll_gemini/fixes'
9
+ require 'jekyll_gemini/publisher'
metadata ADDED
@@ -0,0 +1,219 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-gemini
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jeremy Wilkins
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-12-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jekyll
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.7'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '5.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '3.7'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '5.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: jekyll-gemtext
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '0.1'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '0.1'
47
+ - !ruby/object:Gem::Dependency
48
+ name: bundler
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '2.2'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '2.2'
61
+ - !ruby/object:Gem::Dependency
62
+ name: byebug
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '11.1'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '11.1'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rake
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '13.0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '13.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: rspec
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '3.10'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '3.10'
103
+ - !ruby/object:Gem::Dependency
104
+ name: rubocop
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '1.23'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '1.23'
117
+ - !ruby/object:Gem::Dependency
118
+ name: rubocop-rake
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '0.6'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: '0.6'
131
+ - !ruby/object:Gem::Dependency
132
+ name: rubocop-rspec
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: '2.6'
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - "~>"
143
+ - !ruby/object:Gem::Version
144
+ version: '2.6'
145
+ - !ruby/object:Gem::Dependency
146
+ name: simplecov
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - "~>"
150
+ - !ruby/object:Gem::Version
151
+ version: '0.21'
152
+ type: :development
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: '0.21'
159
+ - !ruby/object:Gem::Dependency
160
+ name: yard
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - "~>"
164
+ - !ruby/object:Gem::Version
165
+ version: 0.9.26
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - "~>"
171
+ - !ruby/object:Gem::Version
172
+ version: 0.9.26
173
+ description: |
174
+ Plugin for Jekyll to publish your Jekyll site to both the Web and
175
+ Geminispace from the same set of source Pages and Posts
176
+ email:
177
+ - jeb@jdwilkins.co.uk
178
+ executables: []
179
+ extensions: []
180
+ extra_rdoc_files: []
181
+ files:
182
+ - Gemfile
183
+ - LICENSE.txt
184
+ - README.gmi
185
+ - Rakefile
186
+ - jekyll-gemini.gemspec
187
+ - lib/jekyll-gemini.rb
188
+ - lib/jekyll_gemini.rb
189
+ - lib/jekyll_gemini/capsule.rb
190
+ - lib/jekyll_gemini/command.rb
191
+ - lib/jekyll_gemini/configuration.rb
192
+ - lib/jekyll_gemini/converter.rb
193
+ - lib/jekyll_gemini/fixes.rb
194
+ - lib/jekyll_gemini/publisher.rb
195
+ homepage: https://github.com/jebw/jekyll-gemini
196
+ licenses:
197
+ - MIT
198
+ metadata:
199
+ rubygems_mfa_required: 'true'
200
+ post_install_message:
201
+ rdoc_options: []
202
+ require_paths:
203
+ - lib
204
+ required_ruby_version: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: 2.5.0
209
+ required_rubygems_version: !ruby/object:Gem::Requirement
210
+ requirements:
211
+ - - ">="
212
+ - !ruby/object:Gem::Version
213
+ version: '0'
214
+ requirements: []
215
+ rubygems_version: 3.1.4
216
+ signing_key:
217
+ specification_version: 4
218
+ summary: Jekyll plugin to publish to Geminispace
219
+ test_files: []