lifer 0.2.0 → 0.4.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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +1 -1
  3. data/.gitignore +1 -0
  4. data/CHANGELOG.md +34 -0
  5. data/Gemfile +9 -0
  6. data/Gemfile.lock +110 -25
  7. data/LICENSE +18 -0
  8. data/README.md +79 -14
  9. data/Rakefile +2 -4
  10. data/bin/lifer +4 -2
  11. data/lib/lifer/brain.rb +171 -21
  12. data/lib/lifer/builder/html/from_erb.rb +92 -0
  13. data/lib/lifer/builder/html/from_liquid/drops/collection_drop.rb +40 -0
  14. data/lib/lifer/builder/html/from_liquid/drops/collections_drop.rb +40 -0
  15. data/lib/lifer/builder/html/from_liquid/drops/entry_drop.rb +63 -0
  16. data/lib/lifer/builder/html/from_liquid/drops/frontmatter_drop.rb +45 -0
  17. data/lib/lifer/builder/html/from_liquid/drops/settings_drop.rb +42 -0
  18. data/lib/lifer/builder/html/from_liquid/drops.rb +15 -0
  19. data/lib/lifer/builder/html/from_liquid/filters.rb +27 -0
  20. data/lib/lifer/builder/html/from_liquid/layout_tag.rb +67 -0
  21. data/lib/lifer/builder/html/from_liquid/liquid_env.rb +30 -0
  22. data/lib/lifer/builder/html/from_liquid.rb +109 -0
  23. data/lib/lifer/builder/html.rb +107 -51
  24. data/lib/lifer/builder/rss.rb +113 -0
  25. data/lib/lifer/builder/txt.rb +60 -0
  26. data/lib/lifer/builder.rb +100 -1
  27. data/lib/lifer/cli.rb +105 -0
  28. data/lib/lifer/collection.rb +87 -8
  29. data/lib/lifer/config.rb +159 -31
  30. data/lib/lifer/dev/response.rb +61 -0
  31. data/lib/lifer/dev/router.rb +44 -0
  32. data/lib/lifer/dev/server.rb +97 -0
  33. data/lib/lifer/entry/html.rb +39 -0
  34. data/lib/lifer/entry/markdown.rb +162 -0
  35. data/lib/lifer/entry/txt.rb +41 -0
  36. data/lib/lifer/entry.rb +142 -41
  37. data/lib/lifer/message.rb +58 -0
  38. data/lib/lifer/selection/all_markdown.rb +16 -0
  39. data/lib/lifer/selection/included_in_feeds.rb +15 -0
  40. data/lib/lifer/selection.rb +79 -0
  41. data/lib/lifer/shared/finder_methods.rb +35 -0
  42. data/lib/lifer/shared.rb +6 -0
  43. data/lib/lifer/templates/cli.txt.erb +10 -0
  44. data/lib/lifer/templates/config.yaml +77 -0
  45. data/lib/lifer/templates/its-a-living.png +0 -0
  46. data/lib/lifer/templates/layout.html.erb +1 -1
  47. data/lib/lifer/uri_strategy/pretty.rb +14 -6
  48. data/lib/lifer/uri_strategy/pretty_root.rb +24 -0
  49. data/lib/lifer/uri_strategy/pretty_yyyy_mm_dd.rb +32 -0
  50. data/lib/lifer/uri_strategy/root.rb +17 -0
  51. data/lib/lifer/uri_strategy/simple.rb +10 -6
  52. data/lib/lifer/uri_strategy.rb +46 -6
  53. data/lib/lifer/utilities.rb +117 -0
  54. data/lib/lifer/version.rb +3 -0
  55. data/lib/lifer.rb +130 -23
  56. data/lifer.gemspec +12 -6
  57. data/locales/en.yml +54 -0
  58. metadata +149 -9
  59. data/lib/lifer/layout.rb +0 -25
  60. data/lib/lifer/templates/config +0 -4
  61. data/lib/lifer/uri_strategy/base.rb +0 -15
@@ -1,13 +1,53 @@
1
+ # A URI strategy is used by collections and builders to determine the output
2
+ # path of each entry. Depending on the strategy used, the output URI can be
3
+ # very different. For example, given:
4
+ #
5
+ # Input file: 2020-01-01-my-trip-to-greece.md
6
+ #
7
+ # The output could be many things depending on the configured URI strategy:
8
+ #
9
+ # Output file: https://example.com/my-trip-to-greece.html
10
+ # Output file: https://example.com/2020/my-trip-to-greece/index.html
11
+ # Output file: https://example.com/my-trip-to-greece-foo-bar-foo.html
12
+ #
13
+ # URI strategies are configured per collection.
14
+ #
1
15
  class Lifer::URIStrategy
16
+ include Lifer::Shared::FinderMethods
17
+
2
18
  class << self
3
- def find_by_name(name)
4
- self.const_get name.capitalize
5
- rescue NameError => error
6
- raise StandardError, "no URI strategy '#{name}'"
7
- end
19
+ attr_accessor :name
8
20
  end
21
+
22
+ attr_reader :root
23
+
24
+ def initialize(root:)
25
+ @root = root
26
+ end
27
+
28
+ # This method should always return the path to the file in the format
29
+ # specified by the current URI strategy. For example, if the URI strategy was
30
+ # to indexify every entry (the "pretty" strategy), input to output would look
31
+ # like:
32
+ #
33
+ # entry-name.md ---> entry-name/index.html
34
+ #
35
+ # @raise [NotImplementedError] This method must be implemented on each
36
+ # subclass.
37
+ # @return [String] The path to the built output file.
38
+ def output_file(entry)
39
+ raise NotImplementedError, I18n.t("shared.not_implemented_method")
40
+ end
41
+
42
+ private
43
+
44
+ def file_extension(entry) = entry.class.output_extension
45
+
46
+ self.name = :uri_strategy
9
47
  end
10
48
 
11
- require_relative "uri_strategy/base"
12
49
  require_relative "uri_strategy/pretty"
50
+ require_relative "uri_strategy/pretty_root"
51
+ require_relative "uri_strategy/pretty_yyyy_mm_dd"
52
+ require_relative "uri_strategy/root"
13
53
  require_relative "uri_strategy/simple"
@@ -1,5 +1,94 @@
1
+ # A module namespace for any weird utilities that are used pseudo-globally.
2
+ # Ensure that these are actually useful globally, though. :-)
3
+ #
1
4
  module Lifer::Utilities
2
5
  class << self
6
+ # Output a string using bold escape sequences to the output TTY text.
7
+ #
8
+ # @param string [String] The string to display in bold.
9
+ # @return [String] The string, but in bold.
10
+ def bold_text(string)
11
+ "\e[1m#{string}\e[0m"
12
+ end
13
+
14
+ # Given a string path, classify it into a namespaced Ruby constant. If the
15
+ # constant does not exist, we raise a helpful error. For example:
16
+ #
17
+ # Given: my/class_name/that_exists
18
+ # Result: My::ClassName::ThatExists
19
+ #
20
+ # FIXME:
21
+ # Note that this method is currently a bit naive. It cannot politely
22
+ # transform classes with many caps in them (i.e. `URIStrategy`) without
23
+ # being given an exact match (`URIStrategy`) or a broken-looking one
24
+ # (`u_r_i_strategy`).
25
+ #
26
+ # @param string_constant [String] A string that maps to a Ruby constant.
27
+ # @return [Class, Module]
28
+ # @raise [RuntimeError]
29
+ def classify(string_constant)
30
+ Object.const_get camelize(string_constant)
31
+ rescue NameError => exception
32
+ raise I18n.t(
33
+ "utilities.classify_error",
34
+ string_constant:,
35
+ camel_cased_string_constant: camelize(string_constant)
36
+ )
37
+ end
38
+
39
+ # Takes a date and renders it in ISO 8601 format.
40
+ #
41
+ # @param datetime [Date, Time, DateTime, String] A representation of a date.
42
+ # @return [String] An ISO 8601 representation of that date.
43
+ def date_as_iso8601(datetime)
44
+ return unless (data = DateTime.parse(datetime.to_s))
45
+
46
+ data.strftime("%Y-%m-%dT%H:%M:%S%:z")
47
+ rescue Date::Error
48
+ nil
49
+ end
50
+
51
+ # Given a path, figure out what the extension is. It supports
52
+ # multi-extensions like ".html.erb".
53
+ #
54
+ # @param path [Pathname, String] The path to a file.
55
+ # @return [String] The extension (i.e. ".html.erb").
56
+ def file_extension(path)
57
+ File.basename(path.to_s.downcase).match(/(?<=.)\..*/).to_s
58
+ end
59
+
60
+ # Given any string, normalize it into a "kabab-case", single-word string.
61
+ #
62
+ # Input: "Hi, how are you?"
63
+ # Output: "hi-how-are-you"
64
+ #
65
+ # @param string [String] Any string.
66
+ # @return [String] The kabab-cased output.
67
+ def handleize(string) = parameterize(string, separator: "-")
68
+
69
+ # Given a hash, take all of its keys (and sub-keys) and convert them into
70
+ # strings.
71
+ #
72
+ # @param hash [Hash] Any hash.
73
+ # @return [Hash] The hash with keys transformed to strings.
74
+ def stringify_keys(hash)
75
+ stringified_hash = {}
76
+
77
+ hash.each do |key, value|
78
+ stringified_hash[(key.to_s rescue key) || key] =
79
+ value.is_a?(Hash) ? stringify_keys(value) : value
80
+
81
+ stringify_keys(value) if value.is_a?(Hash)
82
+ end
83
+
84
+ stringified_hash
85
+ end
86
+
87
+ # Given a hash, take all of its keys (and sub-keys) and convert them into
88
+ # symbols.
89
+ #
90
+ # @param hash [Hash] Any hash.
91
+ # @return [Hash] The hash with keys transformed to symbols.
3
92
  def symbolize_keys(hash)
4
93
  symbolized_hash = {}
5
94
 
@@ -12,5 +101,33 @@ module Lifer::Utilities
12
101
 
13
102
  symbolized_hash
14
103
  end
104
+
105
+ private
106
+
107
+ def camelize(string)
108
+ string = string.to_s
109
+ string
110
+ .gsub("/", "::")
111
+ .split("::")
112
+ .map(&:capitalize)
113
+ .map { |mod| mod.split("_").map(&:capitalize).join }
114
+ .join("::")
115
+ end
116
+
117
+ def parameterize(string, separator: "-", preserve_case: false)
118
+ text = string.gsub(/[^A-z0-9\-_]+/, separator)
119
+
120
+ unless separator.nil? || separator.empty?
121
+ re_sep = Regexp.escape(separator)
122
+ re_duplicate_separator = /#{re_sep}{2,}/
123
+ re_leading_trailing_separator = /^#{re_sep}|#{re_sep}$/
124
+
125
+ text.gsub!(re_duplicate_separator, separator)
126
+ text.gsub!(re_leading_trailing_separator, "")
127
+ end
128
+
129
+ text.downcase! unless preserve_case
130
+ text
131
+ end
15
132
  end
16
133
  end
@@ -0,0 +1,3 @@
1
+ module Lifer
2
+ VERSION = "0.4.0"
3
+ end
data/lib/lifer.rb CHANGED
@@ -2,21 +2,22 @@
2
2
 
3
3
  require "set"
4
4
 
5
- require_relative "lifer/brain"
6
- require_relative "lifer/builder"
7
- require_relative "lifer/collection"
8
- require_relative "lifer/config"
9
- require_relative "lifer/entry"
10
- require_relative "lifer/layout"
11
- require_relative "lifer/uri_strategy"
12
-
5
+ # The root Lifer module is a great entrypoint into the system, with convenience
6
+ # methods to access global resources like collections and configuration settings.
7
+ #
13
8
  module Lifer
9
+ # Lifer considers files and directories that have the following names or
10
+ # contain the following patterns special and ignoreable when they're at the
11
+ # root of the Lifer project.
12
+ #
14
13
  IGNORE_DIRECTORIES = [
15
14
  "assets",
16
15
  "bin",
17
16
  "vendor"
18
17
  ]
19
18
 
19
+ # Lifer projects ignore files and directories that contain particular patterns.
20
+ #
20
21
  IGNORE_PATTERNS = [
21
22
  "^(\\.)", # Starts with a dot.
22
23
  "^(_)", # Starts with an underscore.
@@ -24,32 +25,138 @@ module Lifer
24
25
  ] | IGNORE_DIRECTORIES.map { |d| "^(#{d})" }
25
26
 
26
27
  class << self
27
- def brain
28
- @@brain ||= Lifer::Brain.init(root: Dir.pwd)
28
+ # The first time `Lifer.brain` is referenced, we build a new `Lifer::Brain`
29
+ # object that is used and reused until the current process has ended.
30
+ #
31
+ # @param root [String] The absolute path to the Lifer project root.
32
+ # @param config_file [String] The absolute path to the Lifer project's
33
+ # configuration file.
34
+ # @return [Lifer::Brain] A brain!
35
+ def brain(root: Dir.pwd, config_file: nil)
36
+ @@brain ||= Lifer::Brain.init root:, config_file:
29
37
  end
30
38
 
31
- def build!
32
- brain.build!
33
- end
39
+ # Initiates the Lifer build process.
40
+ #
41
+ # @param environment [Symbol] The name of the current Lifer environment.
42
+ # Valid environments are `:build` or `:serve`.
43
+ # @return [void]
44
+ def build!(environment: :build) = (brain.build! environment:)
45
+
46
+ # List all collections in the project. By default, selections are also
47
+ # included.
48
+ #
49
+ # @param without_selections [boolean] Whether to include selections in the list.
50
+ # (Default: false.)
51
+ # @return [Array<Lifer::Collection>] A list of all collections.
52
+ def collections(without_selections: false)
53
+ return brain.collections unless without_selections
34
54
 
35
- def collections
36
- brain.collections
55
+ brain.collections.select { _1.class == Lifer::Collection }
37
56
  end
38
57
 
58
+ # Used to locate the configuration file being used by the current Lifer
59
+ # project.
60
+ #
61
+ # @return [Pathname] The path to the current Lifer config file.
62
+ def config_file = brain.config.file
63
+
64
+ # A set of all entries currently in the project.
65
+ #
66
+ # FIXME: Do we need this as well as `Lifer.manifest`?
67
+ #
68
+ # @return [Set] All entries.
69
+ def entry_manifest = brain.entry_manifest
70
+
71
+ # This convenience method locates the Ruby gem root, which is always
72
+ # distinct from the Lifer project root. This is helpful, for example, if
73
+ # default templates provided by the gem are required in the current project.
74
+ #
75
+ # @return [String] The absolute path to the installed Lifer gem root.
76
+ def gem_root = File.dirname(__dir__)
77
+
78
+ # Check if the given path matches the Lifer ignore patterns.
79
+ #
80
+ # @param directory_or_file [String] The path to a directory or file.
81
+ # @return [boolean] True if the directory of file is ignoreable.
39
82
  def ignoreable?(directory_or_file)
40
83
  directory_or_file.match?(/#{IGNORE_PATTERNS.join("|")}/)
41
84
  end
42
85
 
43
- def manifest
44
- brain.manifest
45
- end
86
+ # A set of all entries currently in the project.
87
+ #
88
+ # FIXME: Do we need this as well as `Lifer.manifest`?
89
+ #
90
+ # @return [Set] All entries.
91
+ def manifest = brain.manifest
46
92
 
47
- def root
48
- brain.root
49
- end
93
+ # The build directory for the Lifer project.
94
+ #
95
+ # @return [Pathname] The absolute path to the directory where the Lifer
96
+ # project would be built to.
97
+ def output_directory = brain.output_directory
98
+
99
+ # Register new settings so that they are "safe" and can be read from a Lifer
100
+ # configuration file. Unregistered settings are ignored.
101
+ #
102
+ # Example usage:
103
+ #
104
+ # register_settings(
105
+ # :hidden,
106
+ # :birthday,
107
+ # jsonfeed: [:enabled, :url, :style]
108
+ # )
109
+ #
110
+ # @overload register_settings(setting, ...)
111
+ # @param setting [Symbol, Hash] A setting or setting tree to be registered.
112
+ # @param ... [Symbol, Hash] More settings or settings trees to be
113
+ # registered.
114
+ # @return [void]
115
+ def register_settings(*settings) = brain.config.register_settings(*settings)
116
+
117
+ # The project brain.
118
+ #
119
+ # @return [Lifer::Brain] The project brain.
120
+ def root = brain.root
50
121
 
51
- def settings
52
- brain.config.settings
122
+ # Given a path to a setting, with or without a collection scope, get the
123
+ # current configured value for that setting.
124
+ #
125
+ # Note that if a collection does not have a setting set, the setting
126
+ # returned will be the Lifer root collection setting or the default setting
127
+ # unless the `:strict` keyword argument is set to `true`.
128
+ #
129
+ # @overload setting(..., collection: nil, strict: false)
130
+ # @param ... [Symbol] A list of settings to traverse the settings tree with.
131
+ # @param collection [Lifer::Collection] The collection scope for the
132
+ # wanted setting.
133
+ # @param strict [boolean] Choose whether to strictly return the collection
134
+ # setting or to fallback to the Lifer root and default settings.
135
+ # (Default: false.)
136
+ # @return [String, NilClass] The value of the best in-scope setting.
137
+ def setting(*name, collection: nil, strict: false)
138
+ brain.setting *name, collection: collection, strict: strict
53
139
  end
140
+
141
+ # The project's current settings tree.
142
+ #
143
+ # @return [Hash] The `Lifer::Config#settings`.
144
+ def settings = brain.config.settings
54
145
  end
55
146
  end
147
+
148
+ require "i18n"
149
+ I18n.load_path += Dir["%s/locales/*.yml" % Lifer.gem_root]
150
+ I18n.available_locales = [:en]
151
+
152
+ # `Lifer::Shared` contains modules that that may or may not be included on other
153
+ # classes required below.
154
+ #
155
+ require_relative "lifer/shared"
156
+
157
+ require_relative "lifer/brain"
158
+ require_relative "lifer/builder"
159
+ require_relative "lifer/collection"
160
+ require_relative "lifer/entry"
161
+ require_relative "lifer/message"
162
+ require_relative "lifer/uri_strategy"
data/lifer.gemspec CHANGED
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Lifer
4
- VERSION = "0.2.0"
5
- end
3
+ require_relative "lib/lifer/version"
6
4
 
7
5
  Gem::Specification.new do |spec|
8
6
  spec.name = "lifer"
@@ -13,7 +11,7 @@ Gem::Specification.new do |spec|
13
11
  spec.summary = "Minimal static weblog generator."
14
12
  spec.description = "Minimal static weblog generator. Good RSS feeds."
15
13
  spec.homepage = "https://github.com/benjaminwil/lifer"
16
- spec.required_ruby_version = ">= 3.1"
14
+ spec.required_ruby_version = ">= 3.3"
17
15
 
18
16
  spec.metadata["allowed_push_host"] = "https://rubygems.org"
19
17
 
@@ -30,11 +28,19 @@ Gem::Specification.new do |spec|
30
28
  .reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
31
29
  end
32
30
 
33
- spec.bindir = "exe"
34
- spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
31
+ spec.bindir = "bin"
32
+ spec.executables =
33
+ spec.files.grep(%r{\Abin/}) { |bin_file| File.basename(bin_file) }
35
34
  spec.require_paths = ["lib"]
36
35
 
36
+ spec.add_dependency "i18n", "< 2"
37
37
  spec.add_dependency "kramdown", "~> 2.4"
38
+ spec.add_dependency "liquid", ["~> 5.6", "< 6"]
39
+ spec.add_dependency "listen", "< 4"
40
+ spec.add_dependency "puma", "< 7"
41
+ spec.add_dependency "rack", "< 4"
42
+ spec.add_dependency "rss"
38
43
 
39
44
  spec.add_development_dependency "debug"
45
+ spec.add_development_dependency "nokogiri"
40
46
  end
data/locales/en.yml ADDED
@@ -0,0 +1,54 @@
1
+ en:
2
+ builder:
3
+ file_conflict_error: "Cannot build HTML file because `%{path}` already exists."
4
+ prebuild_failure: >
5
+ Lifer failed to complete building... A prebuild step failed to execute: %{exception}
6
+ html:
7
+ no_builder_error: No builder for layout file `%{file}` with type `%{type}`. Aborting!
8
+ cli:
9
+ bad_port: >
10
+ Problem with port argument: %{exception}
11
+ banner:
12
+ description: >
13
+ %{program_name}, the static site generator
14
+ subcommands: Subcommands
15
+ options: Options
16
+ usage: Usage
17
+ no_subcommand: >
18
+ %{subcommand} is not a supported subcommand. Running %{default_command} instead.
19
+ options:
20
+ config: Specify the path to a Lifer configuration file.
21
+ dump_default_config: Print the default configuration file to STDOUT and exit.
22
+ port: Specify a custom port for the dev server.
23
+ root: Specify the path to the Lifer project root.
24
+ subcommands:
25
+ build: Build the Lifer project as configured in your Lifer configuration file.
26
+ help: Display help text for the Lifer commandline interface.
27
+ serve: Run a Lifer development server. (http://localhost:9292 by default.)
28
+ dev:
29
+ router:
30
+ content_type_not_implemented: no content type defined for files like %{path} yet
31
+ four_oh_four: 404 Not Found
32
+ entry:
33
+ feedable_error: >
34
+ please set `%{entry_class}.include_in_feeds` to true or false
35
+ markdown:
36
+ date_error: "[%{filename}]: %{error}"
37
+ no_date_metadata: "[%{filename}]: no date metadata"
38
+ not_found: >
39
+ file "%{file}" does not exist
40
+ config:
41
+ no_config_file_at: No configuration file at %{file}. Using default configuration.
42
+ message:
43
+ prefix:
44
+ error: ERR
45
+ selection:
46
+ entries_not_implemented: all selections must implement the `#entries` method
47
+ layouts_not_allowed: selections do not have layout files
48
+ shared:
49
+ not_implemented_method: subclasses must implement this method
50
+ finder_methods:
51
+ unknown_class: no class with name "%{name}"
52
+ utilities:
53
+ classify_error: >
54
+ could not find constant for path "%{string_constant}" (%{camel_cased_string_constant})
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lifer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - benjamin wil
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-07 00:00:00.000000000 Z
11
+ date: 2025-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: i18n
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "<"
18
+ - !ruby/object:Gem::Version
19
+ version: '2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "<"
25
+ - !ruby/object:Gem::Version
26
+ version: '2'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: kramdown
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -24,6 +38,82 @@ dependencies:
24
38
  - - "~>"
25
39
  - !ruby/object:Gem::Version
26
40
  version: '2.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: liquid
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.6'
48
+ - - "<"
49
+ - !ruby/object:Gem::Version
50
+ version: '6'
51
+ type: :runtime
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: '5.6'
58
+ - - "<"
59
+ - !ruby/object:Gem::Version
60
+ version: '6'
61
+ - !ruby/object:Gem::Dependency
62
+ name: listen
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "<"
66
+ - !ruby/object:Gem::Version
67
+ version: '4'
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "<"
73
+ - !ruby/object:Gem::Version
74
+ version: '4'
75
+ - !ruby/object:Gem::Dependency
76
+ name: puma
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "<"
80
+ - !ruby/object:Gem::Version
81
+ version: '7'
82
+ type: :runtime
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "<"
87
+ - !ruby/object:Gem::Version
88
+ version: '7'
89
+ - !ruby/object:Gem::Dependency
90
+ name: rack
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "<"
94
+ - !ruby/object:Gem::Version
95
+ version: '4'
96
+ type: :runtime
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "<"
101
+ - !ruby/object:Gem::Version
102
+ version: '4'
103
+ - !ruby/object:Gem::Dependency
104
+ name: rss
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :runtime
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
27
117
  - !ruby/object:Gem::Dependency
28
118
  name: debug
29
119
  requirement: !ruby/object:Gem::Requirement
@@ -38,17 +128,36 @@ dependencies:
38
128
  - - ">="
39
129
  - !ruby/object:Gem::Version
40
130
  version: '0'
131
+ - !ruby/object:Gem::Dependency
132
+ name: nokogiri
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
41
145
  description: Minimal static weblog generator. Good RSS feeds.
42
146
  email:
43
147
  - benjamin@super.gd
44
- executables: []
148
+ executables:
149
+ - console
150
+ - lifer
151
+ - setup
45
152
  extensions: []
46
153
  extra_rdoc_files: []
47
154
  files:
48
155
  - ".github/workflows/main.yml"
49
156
  - ".gitignore"
157
+ - CHANGELOG.md
50
158
  - Gemfile
51
159
  - Gemfile.lock
160
+ - LICENSE
52
161
  - README.md
53
162
  - Rakefile
54
163
  - bin/console
@@ -58,18 +167,49 @@ files:
58
167
  - lib/lifer/brain.rb
59
168
  - lib/lifer/builder.rb
60
169
  - lib/lifer/builder/html.rb
170
+ - lib/lifer/builder/html/from_erb.rb
171
+ - lib/lifer/builder/html/from_liquid.rb
172
+ - lib/lifer/builder/html/from_liquid/drops.rb
173
+ - lib/lifer/builder/html/from_liquid/drops/collection_drop.rb
174
+ - lib/lifer/builder/html/from_liquid/drops/collections_drop.rb
175
+ - lib/lifer/builder/html/from_liquid/drops/entry_drop.rb
176
+ - lib/lifer/builder/html/from_liquid/drops/frontmatter_drop.rb
177
+ - lib/lifer/builder/html/from_liquid/drops/settings_drop.rb
178
+ - lib/lifer/builder/html/from_liquid/filters.rb
179
+ - lib/lifer/builder/html/from_liquid/layout_tag.rb
180
+ - lib/lifer/builder/html/from_liquid/liquid_env.rb
181
+ - lib/lifer/builder/rss.rb
182
+ - lib/lifer/builder/txt.rb
183
+ - lib/lifer/cli.rb
61
184
  - lib/lifer/collection.rb
62
185
  - lib/lifer/config.rb
186
+ - lib/lifer/dev/response.rb
187
+ - lib/lifer/dev/router.rb
188
+ - lib/lifer/dev/server.rb
63
189
  - lib/lifer/entry.rb
64
- - lib/lifer/layout.rb
65
- - lib/lifer/templates/config
190
+ - lib/lifer/entry/html.rb
191
+ - lib/lifer/entry/markdown.rb
192
+ - lib/lifer/entry/txt.rb
193
+ - lib/lifer/message.rb
194
+ - lib/lifer/selection.rb
195
+ - lib/lifer/selection/all_markdown.rb
196
+ - lib/lifer/selection/included_in_feeds.rb
197
+ - lib/lifer/shared.rb
198
+ - lib/lifer/shared/finder_methods.rb
199
+ - lib/lifer/templates/cli.txt.erb
200
+ - lib/lifer/templates/config.yaml
201
+ - lib/lifer/templates/its-a-living.png
66
202
  - lib/lifer/templates/layout.html.erb
67
203
  - lib/lifer/uri_strategy.rb
68
- - lib/lifer/uri_strategy/base.rb
69
204
  - lib/lifer/uri_strategy/pretty.rb
205
+ - lib/lifer/uri_strategy/pretty_root.rb
206
+ - lib/lifer/uri_strategy/pretty_yyyy_mm_dd.rb
207
+ - lib/lifer/uri_strategy/root.rb
70
208
  - lib/lifer/uri_strategy/simple.rb
71
209
  - lib/lifer/utilities.rb
210
+ - lib/lifer/version.rb
72
211
  - lifer.gemspec
212
+ - locales/en.yml
73
213
  homepage: https://github.com/benjaminwil/lifer
74
214
  licenses: []
75
215
  metadata:
@@ -85,14 +225,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
85
225
  requirements:
86
226
  - - ">="
87
227
  - !ruby/object:Gem::Version
88
- version: '3.1'
228
+ version: '3.3'
89
229
  required_rubygems_version: !ruby/object:Gem::Requirement
90
230
  requirements:
91
231
  - - ">="
92
232
  - !ruby/object:Gem::Version
93
233
  version: '0'
94
234
  requirements: []
95
- rubygems_version: 3.3.7
235
+ rubygems_version: 3.5.16
96
236
  signing_key:
97
237
  specification_version: 4
98
238
  summary: Minimal static weblog generator.