sawsge 0.1.2 → 0.2.1

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: db8b4aef4881751a78644ad5d9073f8e16502c48729642206cc7f8c21194f847
4
- data.tar.gz: 12d90812a34c228dae1889e9790e6bfda0f5a6afe30a283183f4433eb202fcdc
3
+ metadata.gz: e97f4efdfda6c24333e69d1e5a213ff5cf838886620b6a66253e4b15a270bec7
4
+ data.tar.gz: 9e3d40a49c624280265c5189a20bb95bdab602227e9161925b737f42d0fcd701
5
5
  SHA512:
6
- metadata.gz: 9f7839d4b44fd4a455cea7f0959fbc8ae16406232205a8e469931e6184aabbee9d4187bb5fcca236073aab95613ed0c1fa579d5694e9c5aa603e8e5d4d2291d6
7
- data.tar.gz: 132760b63b2b18f681da97c5352b529b6eb61be97b76151fc74f5be98dd17b5ce02807c9aa0117157b2c5b9b07ba81c73633a6c7719318660a3cf70d935c9527
6
+ metadata.gz: 25633584a07e77f02536dfbe23cba4e91ad68c72b3c55d7def67e48775cb14db57e1d9459d26514bdc7f42261d129fe017b6432e1fc9de54909907dbf74c2e4c
7
+ data.tar.gz: 2aa82092c2e6a97afb34a639f02dd93f4f342c8491232812c6ea0da99782d9092cbb777642b4da0a0d2e495d204da80785395abc87cbf76760b8c8a0959efc6f
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
data/README.md CHANGED
@@ -1,11 +1,12 @@
1
1
  # sawsge
2
+
2
3
  My simple static site generator for blogs or projects.
3
4
 
4
5
  ## Installation
5
6
 
6
7
  Sawsge is availible as a
7
8
  [Gem](https://rubygems.org/gems/sawsge) and as an [AUR
8
- package].
9
+ package](https://aur.archlinux.org/packages/sawsge).
9
10
 
10
11
  Install as a Gem: `gem install sawsge`
11
12
 
@@ -14,10 +15,20 @@ installed.
14
15
 
15
16
  Install from the AUR: `paru -S sawsge`
16
17
 
18
+ ## Usage
19
+
20
+ Run `sawsge [DIRECTORY]` where `[DIRECTORY]` is the source
21
+ directory root. If `[DIRECTORY]` is not provided, Sawsge
22
+ will target `./`
23
+
17
24
  ## File Structure
18
- In the source directory root should exist `header.html`, `footer.html`, and `config.toml`. Additional files may need to exist for different modes.
25
+
26
+ In the source directory root should exist `header.html`,
27
+ `footer.html`, and `config.toml`. Additional files may need
28
+ to exist for different modes.
19
29
 
20
30
  ## Config
31
+
21
32
  Here's an example config for a project:
22
33
  ```toml
23
34
  [general]
@@ -48,10 +59,28 @@ posts_dirname = "post"
48
59
  ```
49
60
 
50
61
  # General Operation
51
- Sawsge makes all links on the site point to directories, so there is no `index.html` at the end of any URL (example.com/thing/index.html vs example.com/thing/). Sawsge will build your website to `out_dirname` in your config; make sure there are no files in there, as they will be deleted!
62
+
63
+ Sawsge makes all links on the site point to directories, so
64
+ there is no `index.html` at the end of any URL
65
+ (example.com/thing/index.html vs example.com/thing/). Sawsge
66
+ will build your website to `out_dirname` in your config;
67
+ make sure there are no files in there, as they will be
68
+ deleted!
52
69
 
53
70
  ## Blog Mode
54
- Blog mode creates a special homepage with the title and a summary of each post, with latest posts at the top. In blog mode, sawsge will look for posts under `posts_dirname` in the config. In `posts_dirname`, each post should be in a directory specifying its date in YYYY/MM/DD format, e.g. `/[posts_dirname]/2021/03/09/index.md`. In its source, the post should include at least one `<h1></h1>` and one `<summary></summary>`HTML block. Both will be used to generate the summary on the front page.
55
71
 
56
- ## Usage
57
- Run `sawsge [dir]` where `[dir]` is the source directory root.
72
+ Blog mode creates a special homepage with the title and a
73
+ summary of each post, with latest posts at the top. In blog
74
+ mode, sawsge will look for posts under `posts_dirname` in
75
+ the config. In `posts_dirname`, each post should be in a
76
+ directory specifying its date in YYYY/MM/DD format, e.g.
77
+ `/[posts_dirname]/2021/03/09/index.md`. In its source, the
78
+ post should include at least one `<h1></h1>` and one
79
+ `<summary></summary>`HTML block. Both will be used to
80
+ generate the summary on the front page.
81
+
82
+ ## Project Mode
83
+
84
+ Project mode is much simpler than blog mode. It performs no
85
+ special handling with different files--each Markdown file
86
+ will be generated as a plain page.
data/bin/sawsge CHANGED
@@ -3,4 +3,4 @@
3
3
 
4
4
  require 'sawsge'
5
5
 
6
- Sawsge.sawsge
6
+ Sawsge.cli
@@ -0,0 +1,23 @@
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
+ # So posts are added to Home in chronological order
14
+ post_paths.reverse!
15
+
16
+ @resource_paths -= post_paths
17
+ @resource_paths.delete home_path
18
+
19
+ post_objects = post_paths.map { |path| Post.new(path, @config) }
20
+ home_object = Home.new(home_path, post_objects, @config)
21
+ @all_objects = post_objects + [home_object]
22
+ end
23
+ end
@@ -0,0 +1,34 @@
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
+ @reserved_filenames = config[:general][:ignore] + [CONFIG_FILENAME, @header_filename, @footer_filename]
28
+
29
+ @external_links_target_blank = config[:general][:external_links_target_blank]
30
+
31
+ @posts_dirname = config[:blog][:posts_dirname]
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Sawsge
4
+ # The homepage
5
+ class Home < Page
6
+ def initialize(path, posts, config)
7
+ super(path, config)
8
+ posts.each_with_index do |post, _i|
9
+ # Adds collapseable summary of each post on the front
10
+ # page
11
+ summary_fragment = Nokogiri::HTML5.fragment <<~HTML
12
+ <details open>
13
+ <summary>
14
+ <a href=\"/#{File.dirname(post.path)}\">#{post.title}</a> <date>#{post.date}</date>
15
+ </summary>
16
+ <p>#{post.summary}</p>
17
+ <a href=\"#{File.dirname(post.path)}\">Read more</a>
18
+ </details>
19
+ HTML
20
+ @document.at_css('footer').add_previous_sibling summary_fragment
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,58 +1,61 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Sawsge
3
+ class Sawsge
4
4
  # An HTML page
5
5
  class Page < Resource
6
6
  attr_reader :title
7
- def initialize(path)
7
+
8
+ def initialize(path, config)
8
9
  super(path)
9
10
  html_body_fragment = PandocRuby.convert(File.new(@path, 'r').read, from: :markdown, to: :html)
10
- @document = Nokogiri::HTML5(HEADER + FOOTER)
11
- @body = Nokogiri::HTML5.fragment(html_body_fragment)
11
+
12
+ header = File.read config.header_path
13
+ footer = File.read config.footer_path
14
+
15
+ # @document = Nokogiri::HTML5(header + footer)
16
+ # @body = Nokogiri::HTML5.fragment(header + html_body_fragment + footer)
17
+ @document = Nokogiri::HTML5(header + html_body_fragment + footer)
12
18
 
13
19
  # Place body fragment after header (and before footer)
14
- header = @document.at_css('header')
15
- @body = header.add_next_sibling(@body)
20
+ # header_location = @document.at_css('header')
21
+ # @body = header.add_next_sibling(@body)
16
22
 
17
23
  # Parse the body fragment instead of the whole document,
18
24
  # as the header may have another h1 within
19
25
  @title = begin
20
- h1 = @body.at_css('h1')
21
- h1 ? h1.content : ''
22
- end
26
+ h1 = @document.at_css('h1')
27
+ h1 ? h1.content : ''
28
+ end
23
29
  @document.at_css('title').content = @title
24
30
 
25
- if EXTERNAL_LINKS_TARGET_BLANK
31
+ if config.external_links_target_blank
26
32
  # For any `a` tag where the href attribute has no
27
33
  # hostname (external link) and no existing `target`
28
34
  # attribute, add an attribute `target` with value
29
35
  # blank. mailto links are also ignored, as common
30
36
  # obfuscation techniques can interfere with Nokogiri.
31
37
  external_links = @document.css('a').reject do |link|
32
- begin
33
38
  uri = URI(link['href'])
34
39
  # If a link is malformed, it's not sawsge's problem
35
40
  # to fix.
36
- rescue URI::InvalidComponentError
37
- false
38
- else
39
- host = uri.host
40
- scheme = uri.scheme
41
- host.nil? or host.empty? or scheme == 'mailto' or (not link['target'].nil?)
42
- end
41
+ rescue URI::InvalidComponentError
42
+ false
43
+ else
44
+ host = uri.host
45
+ scheme = uri.scheme
46
+ host.nil? or host.empty? or scheme == 'mailto' or !link['target'].nil?
43
47
  end
44
48
  external_links.each { |link| link['target'] = '_blank' }
45
49
  end
46
-
47
50
  end
48
51
 
49
- def build
52
+ def build(out_dirname)
50
53
  serialized_html = @document.serialize
51
- out_path = File.join(OUT_DIRNAME, @path.sub('index.md', 'index.html'))
52
- out_dir = File.join(OUT_DIRNAME, File.dirname(@path))
54
+ out_path = File.join(out_dirname, @path.sub('index.md', 'index.html'))
55
+ out_dir = File.join(out_dirname, File.dirname(@path))
53
56
 
54
57
  FileUtils.mkpath out_dir
55
- File.new(out_path, "w").syswrite(serialized_html)
58
+ File.new(out_path, 'w').syswrite(serialized_html)
56
59
  end
57
60
  end
58
61
  end
@@ -1,20 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Sawsge
3
+ class Sawsge
4
4
  # A blogpost style HTML page
5
5
  class Post < Page
6
6
  attr_reader :date, :summary
7
- def initialize(path)
8
- super(path)
7
+
8
+ def initialize(path, config)
9
+ super(path, config)
9
10
 
10
11
  # There's got to be a more idiomatic way to do this! The
11
12
  # current implementation is disguisting.
12
13
  # Also doesn't work if POSTS_DIRNAME is more than 2
13
14
  # directories
14
15
  parts = Pathname.new(@path).each_filename.to_a[1..]
15
- parts.delete(POSTS_DIRNAME)
16
+ parts.delete(config.posts_dirname)
16
17
  @date = "#{parts[0]}-#{parts[1]}-#{parts[2]}"
17
- @body.css('h1').first.add_next_sibling "<date>#{@date}</date>"
18
+ @document.css('h1').first.add_next_sibling "<date>#{@date}</date>"
18
19
 
19
20
  # Look what's in <summary></summary>
20
21
  @summary = @document.css('summary').first.content
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Sawsge
4
- def self.project
3
+ class Sawsge
4
+ def project
5
5
  page_paths = @resource_paths.select { |path| File.extname(path) == '.md' }
6
6
 
7
- @resource_paths.subtract page_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,14 +1,18 @@
1
- module Sawsge
1
+ # frozen_string_literal: true
2
+
3
+ class Sawsge
2
4
  # Any generic file in the website directory
3
5
  class Resource
4
6
  attr_reader :path
7
+
5
8
  def initialize(path)
6
9
  # Path is relative to SRC_DIR, does not include it
7
10
  @path = path
8
11
  end
9
- def build
10
- FileUtils.mkpath File.join(OUT_DIRNAME, File.dirname(@path))
11
- FileUtils.cp @path, File.join(OUT_DIRNAME, @path)
12
+
13
+ def build(out_dirname)
14
+ FileUtils.mkpath File.join(out_dirname, File.dirname(@path))
15
+ FileUtils.cp @path, File.join(out_dirname, @path)
12
16
  end
13
17
  end
14
18
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Sawsge
4
- VERSION = '0.1.2'
3
+ class Sawsge
4
+ VERSION = '0.2.1'
5
5
  end
data/lib/sawsge.rb CHANGED
@@ -5,83 +5,63 @@ require 'nokogiri'
5
5
  require 'pandoc-ruby'
6
6
  require 'pathname'
7
7
  require 'set'
8
- require 'toml'
8
+ require 'tomlrb'
9
9
  require 'uri'
10
+ require 'parallel'
11
+
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
10
25
 
11
- require_relative 'resource'
12
- require_relative 'page'
13
- require_relative 'post'
14
- require_relative 'home'
15
- require_relative 'blog'
16
- require_relative 'project'
17
-
18
- module Sawsge
19
-
26
+ class Sawsge
20
27
  HELP_STRING = 'Usage: sawsge [DIRECTORY]'
21
28
 
22
- SRC_DIR = ARGV[0] || Dir.pwd
23
-
24
29
  CONFIG_FILENAME = 'config.toml'
25
- CONFIG_STRING = File.read(File.join(SRC_DIR, CONFIG_FILENAME))
26
- CONFIG = TOML::Parser.new(CONFIG_STRING).parsed
27
-
28
- OUT_DIRNAME = CONFIG['general']['out_dirname']
29
-
30
- # TODO: Put these in the config
31
- POSTS_DIRNAME = CONFIG['blog']['posts_dirname']
32
-
33
-
34
- HEADER_FILENAME = CONFIG['general']['header_filename']
35
- FOOTER_FILENAME = CONFIG['general']['footer_filename']
36
-
37
- HEADER = HEADER_FILENAME.empty? ? '' : File.read(File.join(SRC_DIR, HEADER_FILENAME))
38
- FOOTER = FOOTER_FILENAME.empty? ? '' : File.read(File.join(SRC_DIR, FOOTER_FILENAME))
39
-
40
- EXTERNAL_LINKS_TARGET_BLANK = CONFIG['general']['external_links_target_blank']
41
-
42
- IGNORE = CONFIG['general']['ignore']
43
-
44
- # Resources that will not be put into the out folder
45
- RESERVED_FILENAMES = [CONFIG_FILENAME, HEADER_FILENAME, FOOTER_FILENAME] + IGNORE
46
-
47
- MODE = CONFIG['general']['mode']
48
30
 
31
+ def initialize(src_dir)
32
+ @config = Config.new(src_dir)
33
+ end
49
34
 
50
- # Returns the first directory in a path, eg.
51
- # `foo/bar/bin.txt` becomes `foo`
52
- def self.top_parent_dir(path)
53
- Pathname.new(path).each_filename.to_a[0]
35
+ def self.cli
36
+ src_dir = ARGV[0] || Dir.pwd
37
+ new(src_dir).build
54
38
  end
55
39
 
56
- def self.sawsge
40
+ def build
57
41
  # Gross, but easy
58
- Dir.chdir SRC_DIR
42
+ Dir.chdir @config.src_dir
59
43
 
60
44
  # Find all files recursively
61
- @resource_paths = Set.new(Dir.glob('**/*').select do |path|
45
+ @resource_paths = Dir.glob('**/*').select do |path|
62
46
  File.file?(path) &&
63
- top_parent_dir(path) != OUT_DIRNAME &&
64
- !RESERVED_FILENAMES.include?(path)
65
- end)
47
+ top_parent_dir(path) != @config.out_dirname &&
48
+ !@config.reserved_filenames.include?(path)
49
+ end
66
50
 
67
51
  @resource_objects = Set.new
68
52
  @all_objects = Set.new
69
53
 
70
-
71
- self.send MODE
54
+ send @config.mode
72
55
 
73
56
  resources = @resource_paths.map { |path| Resource.new(path) }
74
- @all_objects.merge resources
75
-
57
+ @all_objects += resources
76
58
 
77
59
  # Delete any old builds
78
- if Pathname.new(OUT_DIRNAME).exist?
79
- FileUtils.remove_dir OUT_DIRNAME
80
- end
81
- FileUtils.mkpath OUT_DIRNAME
82
-
60
+ FileUtils.remove_dir @config.out_dirname if Pathname.new(@config.out_dirname).exist?
61
+ FileUtils.mkpath @config.out_dirname
83
62
 
84
63
  # Write each file
85
- @all_objects.each { |object| object.build }
64
+ @all_objects.each { |x| x.build @config.out_dirname }
65
+ Parallel.each(@all_object) { |x| x.build @config.out_dirname }
86
66
  end
87
67
  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
- 'LICENSE',
15
- 'README.md',
16
- 'bin/sawsge',
17
- 'sawsge.gemspec',
18
- 'lib/sawsge/version.rb',
19
- 'lib/sawsge.rb',
20
- 'lib/blog.rb',
21
- 'lib/home.rb',
22
- 'lib/page.rb',
23
- 'lib/post.rb',
24
- 'lib/project.rb',
25
- 'lib/resource.rb'
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 'toml', '~> 0.3'
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.1.2
4
+ version: 0.2.1
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-04-19 00:00:00.000000000 Z
11
+ date: 2022-05-03 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: toml
28
+ name: tomlrb
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0.3'
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: '0.3'
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/home.rb DELETED
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Sawsge
4
- # The homepage
5
- class Home < Page
6
- def initialize(path, posts)
7
- super(path)
8
- posts.each do |post|
9
- # Adds collapseable summary of each post on the front
10
- # page
11
- summary_fragment = Nokogiri::HTML5.fragment <<~HTML
12
- <details open>
13
- <summary>
14
- <a href=\"/#{File.dirname(post.path)}\">#{post.title}</a> <date>#{post.date}</date>
15
- </summary>
16
- <p>#{post.summary}</p>
17
- <a href=\"#{File.dirname(post.path)}\">Read more</a>
18
- </details>
19
- HTML
20
- @document.at_css('footer').add_previous_sibling summary_fragment
21
- end
22
- end
23
- end
24
- end