lifer 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +1 -1
  3. data/.gitignore +1 -0
  4. data/CHANGELOG.md +26 -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.rb +116 -0
  22. data/lib/lifer/builder/html.rb +107 -51
  23. data/lib/lifer/builder/rss.rb +113 -0
  24. data/lib/lifer/builder/txt.rb +60 -0
  25. data/lib/lifer/builder.rb +100 -1
  26. data/lib/lifer/cli.rb +105 -0
  27. data/lib/lifer/collection.rb +87 -8
  28. data/lib/lifer/config.rb +159 -31
  29. data/lib/lifer/dev/response.rb +61 -0
  30. data/lib/lifer/dev/router.rb +44 -0
  31. data/lib/lifer/dev/server.rb +97 -0
  32. data/lib/lifer/entry/html.rb +39 -0
  33. data/lib/lifer/entry/markdown.rb +162 -0
  34. data/lib/lifer/entry/txt.rb +41 -0
  35. data/lib/lifer/entry.rb +142 -41
  36. data/lib/lifer/message.rb +58 -0
  37. data/lib/lifer/selection/all_markdown.rb +16 -0
  38. data/lib/lifer/selection/included_in_feeds.rb +15 -0
  39. data/lib/lifer/selection.rb +79 -0
  40. data/lib/lifer/shared/finder_methods.rb +35 -0
  41. data/lib/lifer/shared.rb +6 -0
  42. data/lib/lifer/templates/cli.txt.erb +10 -0
  43. data/lib/lifer/templates/config.yaml +77 -0
  44. data/lib/lifer/templates/its-a-living.png +0 -0
  45. data/lib/lifer/templates/layout.html.erb +1 -1
  46. data/lib/lifer/uri_strategy/pretty.rb +14 -6
  47. data/lib/lifer/uri_strategy/pretty_root.rb +24 -0
  48. data/lib/lifer/uri_strategy/pretty_yyyy_mm_dd.rb +32 -0
  49. data/lib/lifer/uri_strategy/root.rb +17 -0
  50. data/lib/lifer/uri_strategy/simple.rb +10 -6
  51. data/lib/lifer/uri_strategy.rb +46 -6
  52. data/lib/lifer/utilities.rb +117 -0
  53. data/lib/lifer/version.rb +3 -0
  54. data/lib/lifer.rb +130 -23
  55. data/lifer.gemspec +12 -6
  56. data/locales/en.yml +54 -0
  57. metadata +142 -9
  58. data/lib/lifer/layout.rb +0 -25
  59. data/lib/lifer/templates/config +0 -4
  60. 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.3.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", "< 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.3.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: 2024-12-31 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,76 @@ 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: '6'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "<"
53
+ - !ruby/object:Gem::Version
54
+ version: '6'
55
+ - !ruby/object:Gem::Dependency
56
+ name: listen
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "<"
60
+ - !ruby/object:Gem::Version
61
+ version: '4'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "<"
67
+ - !ruby/object:Gem::Version
68
+ version: '4'
69
+ - !ruby/object:Gem::Dependency
70
+ name: puma
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "<"
74
+ - !ruby/object:Gem::Version
75
+ version: '7'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "<"
81
+ - !ruby/object:Gem::Version
82
+ version: '7'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rack
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "<"
88
+ - !ruby/object:Gem::Version
89
+ version: '4'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "<"
95
+ - !ruby/object:Gem::Version
96
+ version: '4'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rss
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
27
111
  - !ruby/object:Gem::Dependency
28
112
  name: debug
29
113
  requirement: !ruby/object:Gem::Requirement
@@ -38,17 +122,36 @@ dependencies:
38
122
  - - ">="
39
123
  - !ruby/object:Gem::Version
40
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: nokogiri
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
41
139
  description: Minimal static weblog generator. Good RSS feeds.
42
140
  email:
43
141
  - benjamin@super.gd
44
- executables: []
142
+ executables:
143
+ - console
144
+ - lifer
145
+ - setup
45
146
  extensions: []
46
147
  extra_rdoc_files: []
47
148
  files:
48
149
  - ".github/workflows/main.yml"
49
150
  - ".gitignore"
151
+ - CHANGELOG.md
50
152
  - Gemfile
51
153
  - Gemfile.lock
154
+ - LICENSE
52
155
  - README.md
53
156
  - Rakefile
54
157
  - bin/console
@@ -58,18 +161,48 @@ files:
58
161
  - lib/lifer/brain.rb
59
162
  - lib/lifer/builder.rb
60
163
  - lib/lifer/builder/html.rb
164
+ - lib/lifer/builder/html/from_erb.rb
165
+ - lib/lifer/builder/html/from_liquid.rb
166
+ - lib/lifer/builder/html/from_liquid/drops.rb
167
+ - lib/lifer/builder/html/from_liquid/drops/collection_drop.rb
168
+ - lib/lifer/builder/html/from_liquid/drops/collections_drop.rb
169
+ - lib/lifer/builder/html/from_liquid/drops/entry_drop.rb
170
+ - lib/lifer/builder/html/from_liquid/drops/frontmatter_drop.rb
171
+ - lib/lifer/builder/html/from_liquid/drops/settings_drop.rb
172
+ - lib/lifer/builder/html/from_liquid/filters.rb
173
+ - lib/lifer/builder/html/from_liquid/layout_tag.rb
174
+ - lib/lifer/builder/rss.rb
175
+ - lib/lifer/builder/txt.rb
176
+ - lib/lifer/cli.rb
61
177
  - lib/lifer/collection.rb
62
178
  - lib/lifer/config.rb
179
+ - lib/lifer/dev/response.rb
180
+ - lib/lifer/dev/router.rb
181
+ - lib/lifer/dev/server.rb
63
182
  - lib/lifer/entry.rb
64
- - lib/lifer/layout.rb
65
- - lib/lifer/templates/config
183
+ - lib/lifer/entry/html.rb
184
+ - lib/lifer/entry/markdown.rb
185
+ - lib/lifer/entry/txt.rb
186
+ - lib/lifer/message.rb
187
+ - lib/lifer/selection.rb
188
+ - lib/lifer/selection/all_markdown.rb
189
+ - lib/lifer/selection/included_in_feeds.rb
190
+ - lib/lifer/shared.rb
191
+ - lib/lifer/shared/finder_methods.rb
192
+ - lib/lifer/templates/cli.txt.erb
193
+ - lib/lifer/templates/config.yaml
194
+ - lib/lifer/templates/its-a-living.png
66
195
  - lib/lifer/templates/layout.html.erb
67
196
  - lib/lifer/uri_strategy.rb
68
- - lib/lifer/uri_strategy/base.rb
69
197
  - lib/lifer/uri_strategy/pretty.rb
198
+ - lib/lifer/uri_strategy/pretty_root.rb
199
+ - lib/lifer/uri_strategy/pretty_yyyy_mm_dd.rb
200
+ - lib/lifer/uri_strategy/root.rb
70
201
  - lib/lifer/uri_strategy/simple.rb
71
202
  - lib/lifer/utilities.rb
203
+ - lib/lifer/version.rb
72
204
  - lifer.gemspec
205
+ - locales/en.yml
73
206
  homepage: https://github.com/benjaminwil/lifer
74
207
  licenses: []
75
208
  metadata:
@@ -85,14 +218,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
85
218
  requirements:
86
219
  - - ">="
87
220
  - !ruby/object:Gem::Version
88
- version: '3.1'
221
+ version: '3.3'
89
222
  required_rubygems_version: !ruby/object:Gem::Requirement
90
223
  requirements:
91
224
  - - ">="
92
225
  - !ruby/object:Gem::Version
93
226
  version: '0'
94
227
  requirements: []
95
- rubygems_version: 3.3.7
228
+ rubygems_version: 3.5.16
96
229
  signing_key:
97
230
  specification_version: 4
98
231
  summary: Minimal static weblog generator.