sawsge 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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