sawsge 0.1.3 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b8cb16b8c9c5893d01c2d1fc0ba82457e24a9f6fcb670781f9990aecac4773ba
4
- data.tar.gz: 9388f1a50ff785504b8e5b9463b45418f25f9b43de33f93838d06742b8ab6e02
3
+ metadata.gz: f223a65f117e97b65f5add838c6365b8de972c979c1eb00ebd5ebda1a0cdb429
4
+ data.tar.gz: 13a566dbe4719111339ee6425db5126e5a9fad659ca1a6e6cf3f3dc9f12e0be3
5
5
  SHA512:
6
- metadata.gz: cb1c6014f224e896b001420fbf3c96a30b16571d1dbadcc05f6d5f623b7bf550692b3dbccd721453ca520a8b74df8ada8e9cccfc9e41c3d31959aa62428c1231
7
- data.tar.gz: 67e941e2c2ea82468bf51b30232fcfb32e9103b4d762336652d29de3211997217d265cafe349b0f74c7db534ef27713974edf26d8d4baeeec25463d4b0b61240
6
+ metadata.gz: 650b402287f9e2bc91d48f3b9bb811797b6ee93466d9b7fa87ca161972a4f0214fa83c6fe94efe40e9b6554cf535d4e42029c2467d48ab36fd6f3155bba65c87
7
+ data.tar.gz: 6dde2b4089bf42cbf9dbc324f071fb620df5b1c4461cb4a8b42175fac749344de92a04662be34984b30335d4e1c9d29b11f7630a23109d92a84493193187015c
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
data/bin/sawsge CHANGED
@@ -3,4 +3,4 @@
3
3
 
4
4
  require 'sawsge'
5
5
 
6
- Sawsge.sawsge
6
+ Sawsge.cli
@@ -1,23 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Sawsge
4
- def self.blog
3
+ class Sawsge
4
+ def blog
5
5
  home_path = 'index.md'
6
6
 
7
7
  # Does not work if you have parent directories for your
8
8
  # posts dir, e.g. you set posts_dirname in config.toml to
9
9
  # foo/bar/baz/etc...
10
- post_paths = resource_paths.select do |path|
11
- top_parent_dir(path) == POSTS_DIRNAME && File.extname(path) == '.md'
10
+ post_paths = @resource_paths.select do |path|
11
+ top_parent_dir(path) == @config.posts_dirname && File.extname(path) == '.md'
12
12
  end
13
13
  # So posts are added to Home in chronological order
14
14
  post_paths.reverse!
15
15
 
16
- @resource_paths.subtract post_paths
16
+ @resource_paths -= post_paths
17
17
  @resource_paths.delete home_path
18
18
 
19
- post_objects = post_paths.map { |path| Post.new(path) }
20
- home_object = Home.new(home_path, post_objects)
19
+ post_objects = post_paths.map { |path| Post.new(path, @config) }
20
+ home_object = Home.new(home_path, post_objects, @config)
21
21
  @all_objects = post_objects + [home_object]
22
22
  end
23
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
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Sawsge
3
+ class Sawsge
4
4
  # The homepage
5
5
  class Home < Page
6
- def initialize(path, posts)
7
- super(path)
8
- posts.each do |post|
6
+ def initialize(path, posts, config)
7
+ super(path, config)
8
+ posts.each_with_index do |post, _i|
9
9
  # Adds collapseable summary of each post on the front
10
10
  # page
11
11
  summary_fragment = Nokogiri::HTML5.fragment <<~HTML
@@ -1,29 +1,34 @@
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
7
 
8
- def initialize(path)
8
+ def initialize(path, config)
9
9
  super(path)
10
10
  html_body_fragment = PandocRuby.convert(File.new(@path, 'r').read, from: :markdown, to: :html)
11
- @document = Nokogiri::HTML5(HEADER + FOOTER)
12
- @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)
13
18
 
14
19
  # Place body fragment after header (and before footer)
15
- header = @document.at_css('header')
16
- @body = header.add_next_sibling(@body)
20
+ # header_location = @document.at_css('header')
21
+ # @body = header.add_next_sibling(@body)
17
22
 
18
23
  # Parse the body fragment instead of the whole document,
19
24
  # as the header may have another h1 within
20
25
  @title = begin
21
- h1 = @body.at_css('h1')
26
+ h1 = @document.at_css('h1')
22
27
  h1 ? h1.content : ''
23
28
  end
24
29
  @document.at_css('title').content = @title
25
30
 
26
- if EXTERNAL_LINKS_TARGET_BLANK
31
+ if config.external_links_target_blank
27
32
  # For any `a` tag where the href attribute has no
28
33
  # hostname (external link) and no existing `target`
29
34
  # attribute, add an attribute `target` with value
@@ -44,10 +49,10 @@ module Sawsge
44
49
  end
45
50
  end
46
51
 
47
- def build
52
+ def build(out_dirname)
48
53
  serialized_html = @document.serialize
49
- out_path = File.join(OUT_DIRNAME, @path.sub('index.md', 'index.html'))
50
- 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))
51
56
 
52
57
  FileUtils.mkpath out_dir
53
58
  File.new(out_path, 'w').syswrite(serialized_html)
@@ -1,21 +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
7
 
8
- def initialize(path)
9
- super(path)
8
+ def initialize(path, config)
9
+ super(path, config)
10
10
 
11
11
  # There's got to be a more idiomatic way to do this! The
12
12
  # current implementation is disguisting.
13
13
  # Also doesn't work if POSTS_DIRNAME is more than 2
14
14
  # directories
15
15
  parts = Pathname.new(@path).each_filename.to_a[1..]
16
- parts.delete(POSTS_DIRNAME)
16
+ parts.delete(config.posts_dirname)
17
17
  @date = "#{parts[0]}-#{parts[1]}-#{parts[2]}"
18
- @body.css('h1').first.add_next_sibling "<date>#{@date}</date>"
18
+ @document.css('h1').first.add_next_sibling "<date>#{@date}</date>"
19
19
 
20
20
  # Look what's in <summary></summary>
21
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,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Sawsge
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(OUT_DIRNAME, File.dirname(@path))
15
- FileUtils.cp @path, File.join(OUT_DIRNAME, @path)
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Sawsge
4
- VERSION = '0.1.3'
3
+ class Sawsge
4
+ VERSION = '0.2.0'
5
5
  end
data/lib/sawsge.rb CHANGED
@@ -5,75 +5,61 @@ 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
10
 
11
- require_relative 'resource'
12
- require_relative 'page'
13
- require_relative 'post'
14
- require_relative 'home'
15
- require_relative 'blog'
16
- require_relative 'project'
11
+ require 'sawsge/resource'
12
+ require 'sawsge/page'
13
+ require 'sawsge/post'
14
+ require 'sawsge/home'
15
+ require 'sawsge/blog'
16
+ require 'sawsge/project'
17
+ require 'sawsge/config'
18
+
19
+ # Returns the first directory in a path, eg.
20
+ # `foo/bar/bin.txt` becomes `foo`
21
+ def top_parent_dir(path)
22
+ Pathname.new(path).each_filename.to_a[0]
23
+ end
17
24
 
18
- module Sawsge
25
+ class Sawsge
19
26
  HELP_STRING = 'Usage: sawsge [DIRECTORY]'
20
27
 
21
- SRC_DIR = ARGV[0] || Dir.pwd
22
-
23
28
  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
29
 
35
- HEADER = HEADER_FILENAME.empty? ? '' : File.read(File.join(SRC_DIR, HEADER_FILENAME))
36
- FOOTER = FOOTER_FILENAME.empty? ? '' : File.read(File.join(SRC_DIR, FOOTER_FILENAME))
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']
30
+ def initialize(src_dir)
31
+ @config = Config.new(src_dir)
32
+ end
46
33
 
47
- # Returns the first directory in a path, eg.
48
- # `foo/bar/bin.txt` becomes `foo`
49
- def self.top_parent_dir(path)
50
- Pathname.new(path).each_filename.to_a[0]
34
+ def self.cli
35
+ src_dir = ARGV[0] || Dir.pwd
36
+ new(src_dir).build
51
37
  end
52
38
 
53
- def self.sawsge
39
+ def build
54
40
  # Gross, but easy
55
- Dir.chdir SRC_DIR
41
+ Dir.chdir @config.src_dir
56
42
 
57
43
  # Find all files recursively
58
- @resource_paths = Set.new(Dir.glob('**/*').select do |path|
44
+ @resource_paths = Dir.glob('**/*').select do |path|
59
45
  File.file?(path) &&
60
- top_parent_dir(path) != OUT_DIRNAME &&
61
- !RESERVED_FILENAMES.include?(path)
62
- end)
46
+ top_parent_dir(path) != @config.out_dirname &&
47
+ !@config.reserved_filenames.include?(path)
48
+ end
63
49
 
64
50
  @resource_objects = Set.new
65
51
  @all_objects = Set.new
66
52
 
67
- send MODE
53
+ send @config.mode
68
54
 
69
55
  resources = @resource_paths.map { |path| Resource.new(path) }
70
- @all_objects.merge resources
56
+ @all_objects += resources
71
57
 
72
58
  # Delete any old builds
73
- FileUtils.remove_dir OUT_DIRNAME if Pathname.new(OUT_DIRNAME).exist?
74
- FileUtils.mkpath OUT_DIRNAME
59
+ FileUtils.remove_dir @config.out_dirname if Pathname.new(@config.out_dirname).exist?
60
+ FileUtils.mkpath @config.out_dirname
75
61
 
76
62
  # Write each file
77
- @all_objects.each(&:build)
63
+ @all_objects.each { |x| x.build @config.out_dirname }
78
64
  end
79
65
  end
data/sawsge.gemspec CHANGED
@@ -10,24 +10,26 @@ 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'
33
35
  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.3
4
+ version: 0.2.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-04-19 00:00:00.000000000 Z
11
+ date: 2022-05-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pandoc-ruby
@@ -25,19 +25,45 @@ 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
34
37
  type: :runtime
35
38
  prerelease: false
36
39
  version_requirements: !ruby/object:Gem::Requirement
37
40
  requirements:
38
41
  - - "~>"
39
42
  - !ruby/object:Gem::Version
40
- version: '0.3'
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
57
+ type: :runtime
58
+ prerelease: false
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - "~>"
62
+ - !ruby/object:Gem::Version
63
+ version: '1.12'
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: 1.12.4
41
67
  description: Sawsge is an opinionated static site generator with TOML-configurable
42
68
  modes for blogs and projects. It takes Markdown files as source and uses Pandoc
43
69
  behind the scences to generate HTML files.
@@ -47,16 +73,18 @@ executables:
47
73
  extensions: []
48
74
  extra_rdoc_files: []
49
75
  files:
76
+ - Gemfile
50
77
  - LICENSE
51
78
  - README.md
52
79
  - 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
80
  - lib/sawsge.rb
81
+ - lib/sawsge/blog.rb
82
+ - lib/sawsge/config.rb
83
+ - lib/sawsge/home.rb
84
+ - lib/sawsge/page.rb
85
+ - lib/sawsge/post.rb
86
+ - lib/sawsge/project.rb
87
+ - lib/sawsge/resource.rb
60
88
  - lib/sawsge/version.rb
61
89
  - sawsge.gemspec
62
90
  homepage: https://github.com/sawshep/sawsge