sawsge 0.1.3 → 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 +4 -4
- data/Gemfile +5 -0
- data/bin/sawsge +1 -1
- data/lib/sawsge/blog.rb +34 -0
- data/lib/sawsge/config.rb +35 -0
- data/lib/{home.rb → sawsge/home.rb} +6 -4
- data/lib/{page.rb → sawsge/page.rb} +23 -12
- data/lib/sawsge/post.rb +22 -0
- data/lib/{project.rb → sawsge/project.rb} +4 -4
- data/lib/{resource.rb → sawsge/resource.rb} +4 -4
- data/lib/sawsge/version.rb +2 -2
- data/lib/sawsge.rb +35 -46
- data/sawsge.gemspec +18 -15
- metadata +59 -11
- data/lib/blog.rb +0 -23
- data/lib/post.rb +0 -24
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b2a7067cfade9bf1831c7bf6f46d09bd23912b8f02ca9739ab3b281383a1348b
|
|
4
|
+
data.tar.gz: 04cb0c0e02a735460b7f3b0688abeac45d771ec702b6a8227d610b134458345c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b458f8adb18c62f8e6b101ecc572ae41bce854e8970aa0564fbec70e7b278bd133795b69ff1255fa13bc7d027fcc4c223cab06bff8fa92c908714f109b6006bd
|
|
7
|
+
data.tar.gz: 4e1da958f57c9b4feacbe0d655e4db6093ef977efb8ed6a544791146582177fe44c96339e54c1710ede9cd317a877228f39cdab7348287c9c236d42f84da56d6
|
data/Gemfile
ADDED
data/bin/sawsge
CHANGED
data/lib/sawsge/blog.rb
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Sawsge
|
|
4
|
+
def blog
|
|
5
|
+
home_path = 'index.md'
|
|
6
|
+
|
|
7
|
+
# Does not work if you have parent directories for your
|
|
8
|
+
# posts dir, e.g. you set posts_dirname in config.toml to
|
|
9
|
+
# foo/bar/baz/etc...
|
|
10
|
+
post_paths = @resource_paths.select do |path|
|
|
11
|
+
top_parent_dir(path) == @config.posts_dirname && File.extname(path) == '.md'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
@resource_paths -= post_paths
|
|
15
|
+
@resource_paths.delete home_path
|
|
16
|
+
|
|
17
|
+
post_objects = post_paths.map { |path| Post.new(path, @config) }
|
|
18
|
+
|
|
19
|
+
post_objects.sort_by! { |x| x.date }
|
|
20
|
+
# Posts are now in reverse chronological order
|
|
21
|
+
|
|
22
|
+
i_last_nil_date = 0
|
|
23
|
+
while post_objects[i_last_nil_date].date.empty?
|
|
24
|
+
i_last_nil_date += 1
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
post_objects.rotate!(i_last_nil_date).reverse!
|
|
28
|
+
# Posts are now in chronological order with dateless
|
|
29
|
+
# posts being first
|
|
30
|
+
|
|
31
|
+
home_object = Home.new(home_path, post_objects, @config)
|
|
32
|
+
@all_objects = post_objects + [home_object]
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'tomlrb'
|
|
4
|
+
|
|
5
|
+
class Sawsge
|
|
6
|
+
class Config
|
|
7
|
+
attr_reader :external_links_target_blank,
|
|
8
|
+
:posts_dirname, :footer_filename, :reserved_filenames,
|
|
9
|
+
:src_dir, :out_dirname, :mode, :header_filename,
|
|
10
|
+
:header_path, :footer_path
|
|
11
|
+
|
|
12
|
+
def initialize(src_dir)
|
|
13
|
+
config_path = File.join(src_dir, CONFIG_FILENAME)
|
|
14
|
+
config = Tomlrb.load_file(config_path, symbolize_keys: true)
|
|
15
|
+
|
|
16
|
+
@src_dir = File.expand_path src_dir
|
|
17
|
+
|
|
18
|
+
@out_dirname = config.dig(:general, :out_dirname)
|
|
19
|
+
@mode = config[:general][:mode]
|
|
20
|
+
|
|
21
|
+
@header_filename = config.dig(:general, :header_filename)
|
|
22
|
+
@footer_filename = config.dig(:general, :footer_filename)
|
|
23
|
+
|
|
24
|
+
@header_path = File.expand_path(File.join(@src_dir, @header_filename))
|
|
25
|
+
@footer_path = File.expand_path(File.join(@src_dir, @footer_filename))
|
|
26
|
+
|
|
27
|
+
ignored_files = config[:general][:ignore] || []
|
|
28
|
+
@reserved_filenames = ignored_files + [CONFIG_FILENAME, @header_filename, @footer_filename]
|
|
29
|
+
|
|
30
|
+
@external_links_target_blank = config[:general][:external_links_target_blank] || true
|
|
31
|
+
|
|
32
|
+
@posts_dirname = config[:blog][:posts_dirname]
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
class Sawsge
|
|
4
4
|
# The homepage
|
|
5
5
|
class Home < Page
|
|
6
|
-
def initialize(path, posts)
|
|
7
|
-
super(path)
|
|
8
|
-
|
|
6
|
+
def initialize(path, posts, config)
|
|
7
|
+
super(path, config)
|
|
8
|
+
|
|
9
|
+
posts.each_with_index do |post, _i|
|
|
9
10
|
# Adds collapseable summary of each post on the front
|
|
10
11
|
# page
|
|
11
12
|
summary_fragment = Nokogiri::HTML5.fragment <<~HTML
|
|
@@ -19,6 +20,7 @@ module Sawsge
|
|
|
19
20
|
HTML
|
|
20
21
|
@document.at_css('footer').add_previous_sibling summary_fragment
|
|
21
22
|
end
|
|
23
|
+
|
|
22
24
|
end
|
|
23
25
|
end
|
|
24
26
|
end
|
|
@@ -1,29 +1,40 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
class Sawsge
|
|
4
4
|
# An HTML page
|
|
5
5
|
class Page < Resource
|
|
6
6
|
attr_reader :title
|
|
7
7
|
|
|
8
|
-
def initialize(path)
|
|
8
|
+
def initialize(path, config)
|
|
9
9
|
super(path)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
|
|
11
|
+
markdown = File.read(@path)
|
|
12
|
+
options = {
|
|
13
|
+
:from => :markdown,
|
|
14
|
+
:to => :html
|
|
15
|
+
}
|
|
16
|
+
html_body_fragment = PandocRuby.convert(markdown, options)
|
|
17
|
+
|
|
18
|
+
header = File.read config.header_path
|
|
19
|
+
footer = File.read config.footer_path
|
|
20
|
+
|
|
21
|
+
# @document = Nokogiri::HTML5(header + footer)
|
|
22
|
+
# @body = Nokogiri::HTML5.fragment(header + html_body_fragment + footer)
|
|
23
|
+
@document = Nokogiri::HTML5(header + html_body_fragment + footer)
|
|
13
24
|
|
|
14
25
|
# Place body fragment after header (and before footer)
|
|
15
|
-
|
|
16
|
-
@body = header.add_next_sibling(@body)
|
|
26
|
+
# header_location = @document.at_css('header')
|
|
27
|
+
# @body = header.add_next_sibling(@body)
|
|
17
28
|
|
|
18
29
|
# Parse the body fragment instead of the whole document,
|
|
19
30
|
# as the header may have another h1 within
|
|
20
31
|
@title = begin
|
|
21
|
-
h1 = @
|
|
32
|
+
h1 = @document.at_css('h1')
|
|
22
33
|
h1 ? h1.content : ''
|
|
23
34
|
end
|
|
24
35
|
@document.at_css('title').content = @title
|
|
25
36
|
|
|
26
|
-
if
|
|
37
|
+
if config.external_links_target_blank
|
|
27
38
|
# For any `a` tag where the href attribute has no
|
|
28
39
|
# hostname (external link) and no existing `target`
|
|
29
40
|
# attribute, add an attribute `target` with value
|
|
@@ -44,10 +55,10 @@ module Sawsge
|
|
|
44
55
|
end
|
|
45
56
|
end
|
|
46
57
|
|
|
47
|
-
def build
|
|
58
|
+
def build(out_dirname)
|
|
48
59
|
serialized_html = @document.serialize
|
|
49
|
-
out_path = File.join(
|
|
50
|
-
out_dir = File.join(
|
|
60
|
+
out_path = File.join(out_dirname, @path.sub('index.md', 'index.html'))
|
|
61
|
+
out_dir = File.join(out_dirname, File.dirname(@path))
|
|
51
62
|
|
|
52
63
|
FileUtils.mkpath out_dir
|
|
53
64
|
File.new(out_path, 'w').syswrite(serialized_html)
|
data/lib/sawsge/post.rb
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Sawsge
|
|
4
|
+
# A blogpost style HTML page
|
|
5
|
+
class Post < Page
|
|
6
|
+
attr_reader :date, :summary
|
|
7
|
+
|
|
8
|
+
def initialize(path, config)
|
|
9
|
+
super(path, config)
|
|
10
|
+
|
|
11
|
+
# Get the summary and date of the post
|
|
12
|
+
@summary = @document.css('summary').first.content
|
|
13
|
+
# If a date is specified within the <time> tag on the
|
|
14
|
+
# page, use that, otherwise use an empty string
|
|
15
|
+
@date = begin
|
|
16
|
+
date = @document.css('time').first
|
|
17
|
+
date ? date.content : ''
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
def
|
|
3
|
+
class Sawsge
|
|
4
|
+
def project
|
|
5
5
|
page_paths = @resource_paths.select { |path| File.extname(path) == '.md' }
|
|
6
6
|
|
|
7
|
-
@resource_paths
|
|
7
|
+
@resource_paths -= page_paths
|
|
8
8
|
|
|
9
|
-
page_objects = page_paths.map { |path| Page.new(path) }
|
|
9
|
+
page_objects = page_paths.map { |path| Page.new(path, @config) }
|
|
10
10
|
|
|
11
11
|
@all_objects.merge page_objects
|
|
12
12
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
class Sawsge
|
|
4
4
|
# Any generic file in the website directory
|
|
5
5
|
class Resource
|
|
6
6
|
attr_reader :path
|
|
@@ -10,9 +10,9 @@ module Sawsge
|
|
|
10
10
|
@path = path
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
def build
|
|
14
|
-
FileUtils.mkpath File.join(
|
|
15
|
-
FileUtils.cp @path, File.join(
|
|
13
|
+
def build(out_dirname)
|
|
14
|
+
FileUtils.mkpath File.join(out_dirname, File.dirname(@path))
|
|
15
|
+
FileUtils.cp @path, File.join(out_dirname, @path)
|
|
16
16
|
end
|
|
17
17
|
end
|
|
18
18
|
end
|
data/lib/sawsge/version.rb
CHANGED
data/lib/sawsge.rb
CHANGED
|
@@ -3,77 +3,66 @@
|
|
|
3
3
|
require 'fileutils'
|
|
4
4
|
require 'nokogiri'
|
|
5
5
|
require 'pandoc-ruby'
|
|
6
|
+
require 'parallel'
|
|
6
7
|
require 'pathname'
|
|
7
8
|
require 'set'
|
|
8
|
-
require '
|
|
9
|
+
require 'tomlrb'
|
|
9
10
|
require 'uri'
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
require 'sawsge/resource'
|
|
13
|
+
require 'sawsge/page'
|
|
14
|
+
require 'sawsge/post'
|
|
15
|
+
require 'sawsge/home'
|
|
16
|
+
require 'sawsge/blog'
|
|
17
|
+
require 'sawsge/project'
|
|
18
|
+
require 'sawsge/config'
|
|
19
|
+
|
|
20
|
+
# Returns the first directory in a path, eg.
|
|
21
|
+
# `foo/bar/bin.txt` becomes `foo`
|
|
22
|
+
def top_parent_dir(path)
|
|
23
|
+
Pathname.new(path).each_filename.to_a[0]
|
|
24
|
+
end
|
|
17
25
|
|
|
18
|
-
|
|
26
|
+
class Sawsge
|
|
19
27
|
HELP_STRING = 'Usage: sawsge [DIRECTORY]'
|
|
20
28
|
|
|
21
|
-
SRC_DIR = ARGV[0] || Dir.pwd
|
|
22
|
-
|
|
23
29
|
CONFIG_FILENAME = 'config.toml'
|
|
24
|
-
CONFIG_STRING = File.read(File.join(SRC_DIR, CONFIG_FILENAME))
|
|
25
|
-
CONFIG = TOML::Parser.new(CONFIG_STRING).parsed
|
|
26
|
-
|
|
27
|
-
OUT_DIRNAME = CONFIG['general']['out_dirname']
|
|
28
|
-
|
|
29
|
-
# TODO: Put these in the config
|
|
30
|
-
POSTS_DIRNAME = CONFIG['blog']['posts_dirname']
|
|
31
|
-
|
|
32
|
-
HEADER_FILENAME = CONFIG['general']['header_filename']
|
|
33
|
-
FOOTER_FILENAME = CONFIG['general']['footer_filename']
|
|
34
30
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
EXTERNAL_LINKS_TARGET_BLANK = CONFIG['general']['external_links_target_blank']
|
|
39
|
-
|
|
40
|
-
IGNORE = CONFIG['general']['ignore']
|
|
41
|
-
|
|
42
|
-
# Resources that will not be put into the out folder
|
|
43
|
-
RESERVED_FILENAMES = [CONFIG_FILENAME, HEADER_FILENAME, FOOTER_FILENAME] + IGNORE
|
|
44
|
-
|
|
45
|
-
MODE = CONFIG['general']['mode']
|
|
31
|
+
def initialize(src_dir)
|
|
32
|
+
@config = Config.new(src_dir)
|
|
33
|
+
end
|
|
46
34
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
Pathname.new(path).each_filename.to_a[0]
|
|
35
|
+
def self.cli
|
|
36
|
+
src_dir = ARGV[0] || Dir.pwd
|
|
37
|
+
new(src_dir).build
|
|
51
38
|
end
|
|
52
39
|
|
|
53
|
-
def
|
|
40
|
+
def build
|
|
54
41
|
# Gross, but easy
|
|
55
|
-
Dir.chdir
|
|
42
|
+
Dir.chdir @config.src_dir
|
|
56
43
|
|
|
57
44
|
# Find all files recursively
|
|
58
|
-
@resource_paths =
|
|
45
|
+
@resource_paths = Dir.glob('**/*').select do |path|
|
|
59
46
|
File.file?(path) &&
|
|
60
|
-
top_parent_dir(path) !=
|
|
61
|
-
|
|
62
|
-
|
|
47
|
+
top_parent_dir(path) != @config.out_dirname &&
|
|
48
|
+
# Exclude explicitly ignored files
|
|
49
|
+
!@config.reserved_filenames.include?(path)
|
|
50
|
+
end
|
|
63
51
|
|
|
64
52
|
@resource_objects = Set.new
|
|
65
53
|
@all_objects = Set.new
|
|
66
54
|
|
|
67
|
-
|
|
55
|
+
# Execute blog or project specific code.
|
|
56
|
+
send @config.mode
|
|
68
57
|
|
|
69
58
|
resources = @resource_paths.map { |path| Resource.new(path) }
|
|
70
|
-
@all_objects
|
|
59
|
+
@all_objects += resources
|
|
71
60
|
|
|
72
61
|
# Delete any old builds
|
|
73
|
-
FileUtils.remove_dir
|
|
74
|
-
FileUtils.mkpath
|
|
62
|
+
FileUtils.remove_dir @config.out_dirname if Pathname.new(@config.out_dirname).exist?
|
|
63
|
+
FileUtils.mkpath @config.out_dirname
|
|
75
64
|
|
|
76
65
|
# Write each file
|
|
77
|
-
@all_objects.
|
|
66
|
+
Parallel.each(@all_objects) { |x| x.build @config.out_dirname }
|
|
78
67
|
end
|
|
79
68
|
end
|
data/sawsge.gemspec
CHANGED
|
@@ -10,24 +10,27 @@ Gem::Specification.new do |s|
|
|
|
10
10
|
s.description = 'Sawsge is an opinionated static site generator with TOML-configurable modes for blogs and projects. It takes Markdown files as source and uses Pandoc behind the scences to generate HTML files.'
|
|
11
11
|
s.authors = ['Sawyer Shepherd']
|
|
12
12
|
s.email = 'contact@sawyershepherd.org'
|
|
13
|
-
s.files = [
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
13
|
+
s.files = %w[
|
|
14
|
+
Gemfile
|
|
15
|
+
LICENSE
|
|
16
|
+
README.md
|
|
17
|
+
bin/sawsge
|
|
18
|
+
lib/sawsge.rb
|
|
19
|
+
lib/sawsge/blog.rb
|
|
20
|
+
lib/sawsge/config.rb
|
|
21
|
+
lib/sawsge/home.rb
|
|
22
|
+
lib/sawsge/page.rb
|
|
23
|
+
lib/sawsge/post.rb
|
|
24
|
+
lib/sawsge/project.rb
|
|
25
|
+
lib/sawsge/resource.rb
|
|
26
|
+
lib/sawsge/version.rb
|
|
27
|
+
sawsge.gemspec
|
|
27
28
|
]
|
|
28
29
|
s.homepage = 'https://github.com/sawshep/sawsge'
|
|
29
30
|
s.license = 'GPL-3.0'
|
|
30
31
|
s.required_ruby_version = '>= 3.0'
|
|
31
32
|
s.add_runtime_dependency 'pandoc-ruby', '~> 2.1'
|
|
32
|
-
s.add_runtime_dependency '
|
|
33
|
+
s.add_runtime_dependency 'tomlrb', '~> 2.0', '>= 2.0.1'
|
|
34
|
+
s.add_runtime_dependency 'nokogiri', '~> 1.12', '>= 1.12.4'
|
|
35
|
+
s.add_runtime_dependency 'parallel', '~> 1.22', '>= 1.22.1'
|
|
33
36
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sawsge
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sawyer Shepherd
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-
|
|
11
|
+
date: 2022-08-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: pandoc-ruby
|
|
@@ -25,19 +25,65 @@ dependencies:
|
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: '2.1'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
28
|
+
name: tomlrb
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '0
|
|
33
|
+
version: '2.0'
|
|
34
|
+
- - ">="
|
|
35
|
+
- !ruby/object:Gem::Version
|
|
36
|
+
version: 2.0.1
|
|
37
|
+
type: :runtime
|
|
38
|
+
prerelease: false
|
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
40
|
+
requirements:
|
|
41
|
+
- - "~>"
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
version: '2.0'
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: 2.0.1
|
|
47
|
+
- !ruby/object:Gem::Dependency
|
|
48
|
+
name: nokogiri
|
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '1.12'
|
|
54
|
+
- - ">="
|
|
55
|
+
- !ruby/object:Gem::Version
|
|
56
|
+
version: 1.12.4
|
|
34
57
|
type: :runtime
|
|
35
58
|
prerelease: false
|
|
36
59
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
60
|
requirements:
|
|
38
61
|
- - "~>"
|
|
39
62
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
63
|
+
version: '1.12'
|
|
64
|
+
- - ">="
|
|
65
|
+
- !ruby/object:Gem::Version
|
|
66
|
+
version: 1.12.4
|
|
67
|
+
- !ruby/object:Gem::Dependency
|
|
68
|
+
name: parallel
|
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
|
70
|
+
requirements:
|
|
71
|
+
- - "~>"
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: '1.22'
|
|
74
|
+
- - ">="
|
|
75
|
+
- !ruby/object:Gem::Version
|
|
76
|
+
version: 1.22.1
|
|
77
|
+
type: :runtime
|
|
78
|
+
prerelease: false
|
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
80
|
+
requirements:
|
|
81
|
+
- - "~>"
|
|
82
|
+
- !ruby/object:Gem::Version
|
|
83
|
+
version: '1.22'
|
|
84
|
+
- - ">="
|
|
85
|
+
- !ruby/object:Gem::Version
|
|
86
|
+
version: 1.22.1
|
|
41
87
|
description: Sawsge is an opinionated static site generator with TOML-configurable
|
|
42
88
|
modes for blogs and projects. It takes Markdown files as source and uses Pandoc
|
|
43
89
|
behind the scences to generate HTML files.
|
|
@@ -47,16 +93,18 @@ executables:
|
|
|
47
93
|
extensions: []
|
|
48
94
|
extra_rdoc_files: []
|
|
49
95
|
files:
|
|
96
|
+
- Gemfile
|
|
50
97
|
- LICENSE
|
|
51
98
|
- README.md
|
|
52
99
|
- bin/sawsge
|
|
53
|
-
- lib/blog.rb
|
|
54
|
-
- lib/home.rb
|
|
55
|
-
- lib/page.rb
|
|
56
|
-
- lib/post.rb
|
|
57
|
-
- lib/project.rb
|
|
58
|
-
- lib/resource.rb
|
|
59
100
|
- lib/sawsge.rb
|
|
101
|
+
- lib/sawsge/blog.rb
|
|
102
|
+
- lib/sawsge/config.rb
|
|
103
|
+
- lib/sawsge/home.rb
|
|
104
|
+
- lib/sawsge/page.rb
|
|
105
|
+
- lib/sawsge/post.rb
|
|
106
|
+
- lib/sawsge/project.rb
|
|
107
|
+
- lib/sawsge/resource.rb
|
|
60
108
|
- lib/sawsge/version.rb
|
|
61
109
|
- sawsge.gemspec
|
|
62
110
|
homepage: https://github.com/sawshep/sawsge
|
data/lib/blog.rb
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Sawsge
|
|
4
|
-
def self.blog
|
|
5
|
-
home_path = 'index.md'
|
|
6
|
-
|
|
7
|
-
# Does not work if you have parent directories for your
|
|
8
|
-
# posts dir, e.g. you set posts_dirname in config.toml to
|
|
9
|
-
# foo/bar/baz/etc...
|
|
10
|
-
post_paths = resource_paths.select do |path|
|
|
11
|
-
top_parent_dir(path) == POSTS_DIRNAME && File.extname(path) == '.md'
|
|
12
|
-
end
|
|
13
|
-
# So posts are added to Home in chronological order
|
|
14
|
-
post_paths.reverse!
|
|
15
|
-
|
|
16
|
-
@resource_paths.subtract post_paths
|
|
17
|
-
@resource_paths.delete home_path
|
|
18
|
-
|
|
19
|
-
post_objects = post_paths.map { |path| Post.new(path) }
|
|
20
|
-
home_object = Home.new(home_path, post_objects)
|
|
21
|
-
@all_objects = post_objects + [home_object]
|
|
22
|
-
end
|
|
23
|
-
end
|
data/lib/post.rb
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Sawsge
|
|
4
|
-
# A blogpost style HTML page
|
|
5
|
-
class Post < Page
|
|
6
|
-
attr_reader :date, :summary
|
|
7
|
-
|
|
8
|
-
def initialize(path)
|
|
9
|
-
super(path)
|
|
10
|
-
|
|
11
|
-
# There's got to be a more idiomatic way to do this! The
|
|
12
|
-
# current implementation is disguisting.
|
|
13
|
-
# Also doesn't work if POSTS_DIRNAME is more than 2
|
|
14
|
-
# directories
|
|
15
|
-
parts = Pathname.new(@path).each_filename.to_a[1..]
|
|
16
|
-
parts.delete(POSTS_DIRNAME)
|
|
17
|
-
@date = "#{parts[0]}-#{parts[1]}-#{parts[2]}"
|
|
18
|
-
@body.css('h1').first.add_next_sibling "<date>#{@date}</date>"
|
|
19
|
-
|
|
20
|
-
# Look what's in <summary></summary>
|
|
21
|
-
@summary = @document.css('summary').first.content
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|