sitepress-core 4.1.1 → 5.0.0.beta

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.

Potentially problematic release.


This version of sitepress-core might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e15a99e5f701876c5de27b3d6af643814010867088c9bfc58807a099e11a44a8
4
- data.tar.gz: c1ad99de08178a0cd884a6e499712e16fee09501436e674d83e74c34ef533f03
3
+ metadata.gz: ef3344c3cfd0d28305f9f3684d9193008812425f5a0651889e180f7bd1e71738
4
+ data.tar.gz: a61c4ee48c2dc69971d0fef76763bea2bafb215a37c9a1f32e720417149f9316
5
5
  SHA512:
6
- metadata.gz: bd9755ddebfc9f65894a680f73fb4494abb27bc7a7f73b94c66733f2119a15ab7a69b70c22b19b6654af72235a71cc888b1f40b274d4ed8ccb5e53180a221f0b
7
- data.tar.gz: e70dd46ef793fa6734c6fe8859a1f95cd4e12392c416a55994a56f4bed6b07a59b1d2b916fb359c77b3c5e2563278ccfce8b4991fc1c04bb8c6a12fecfb39150
6
+ metadata.gz: 8fece92fa30224dc287d4689441f6db3f9a196ea6d517399b509dcd3cb8bad9232778fd281a3105cb6219966699499e40b3ec4a8fa254125041576bcaee64205
7
+ data.tar.gz: 0c7f1972a0982c708281c29c21ad066ed5f8b7cbef2beced7219439472ac698a439dee672ab41e3c22f77f4f89992dbd81985932fb1594550b90c225d3270a9b
@@ -1,3 +1,5 @@
1
+ require "forwardable"
2
+
1
3
  module Sitepress
2
4
  module Data
3
5
  def self.manage(value)
@@ -70,22 +72,23 @@ module Sitepress
70
72
  end
71
73
 
72
74
  def method_missing(name, *args, **kwargs, &block)
73
- if respond_to? name
74
- self.send name, *args, **kwargs, &block
75
- else
76
- key, modifier, _ = name.to_s.partition(/[!?]/)
77
-
78
- case modifier
79
- when ""
80
- self[key]
81
- when "!"
82
- self.fetch(key, *args, &block)
83
- when "?"
84
- !!self[key]
85
- end
75
+ key, modifier, _ = name.to_s.partition(/[!?]/)
76
+
77
+ case modifier
78
+ when ""
79
+ self[key]
80
+ when "!"
81
+ self.fetch(key, *args, &block)
82
+ when "?"
83
+ !!self[key]
86
84
  end
87
85
  end
88
86
 
87
+ def respond_to_missing?(name, include_private = false)
88
+ key, _, _ = name.to_s.partition(/[!?]/)
89
+ @hash.key?(key) || @hash.key?(key.to_sym) || super
90
+ end
91
+
89
92
  def dig(*args, **kwargs, &block)
90
93
  Data.manage @hash.dig(*args, **kwargs, &block)
91
94
  end
@@ -0,0 +1,54 @@
1
+ require "mime/types"
2
+
3
+ module Sitepress
4
+ # Maps a directory of files into a tree of nodes that form the navigational
5
+ # structure of a website. You can subclass this to handle different file
6
+ # types or directory structures.
7
+ class Directory
8
+ attr_reader :asset_paths
9
+
10
+ def initialize(path)
11
+ @asset_paths = AssetPaths.new(path: path)
12
+ end
13
+
14
+ # Mounts the source files from the path into the given node.
15
+ def mount(node)
16
+ asset_paths.each do |path|
17
+ if path.directory?
18
+ process_directory path, node
19
+ else
20
+ process_asset path, node
21
+ end
22
+ end
23
+ end
24
+
25
+ protected
26
+
27
+ def process_directory(path, node)
28
+ node_name = File.basename path
29
+ self.class.new(path).mount(node.child(node_name))
30
+ end
31
+
32
+ def process_asset(path, node)
33
+ asset = source_for(path)
34
+ node.child(asset.node_name).resources.add_asset(asset, format: asset.format)
35
+ end
36
+
37
+ def source_for(path)
38
+ mime = MIME::Types.type_for(path.to_s).first&.content_type
39
+
40
+ case mime
41
+ when *Image.mime_types
42
+ Image.new(path: path)
43
+ when *Page.mime_types, nil
44
+ # nil handles template files like .erb that have no MIME type
45
+ Page.new(path: path)
46
+ else
47
+ Static.new(path: path)
48
+ end
49
+ end
50
+ end
51
+
52
+ # Backwards compatibility
53
+ AssetNodeMapper = Directory
54
+ end
@@ -0,0 +1,84 @@
1
+ require "mime/types"
2
+ require "fastimage"
3
+
4
+ module Sitepress
5
+ # A source for image files. Extracts dimensions via fastimage.
6
+ #
7
+ # Example:
8
+ # image = Image.new(path: "photos/sunset.jpg")
9
+ # image.width # => 1920
10
+ # image.height # => 1080
11
+ # image.data["width"] # => 1920
12
+ #
13
+ class Image
14
+ MIME_TYPES = %w[image/png image/jpeg image/gif image/webp].freeze
15
+
16
+ def self.mime_types
17
+ MIME_TYPES
18
+ end
19
+
20
+ attr_reader :path
21
+
22
+ def initialize(path:)
23
+ @path = Pathname.new(path)
24
+ end
25
+
26
+ def filename
27
+ path.basename.to_s
28
+ end
29
+
30
+ def node_name
31
+ path.basename(".*").to_s.split(".").first
32
+ end
33
+
34
+ def format
35
+ path.extname.delete(".").to_sym
36
+ end
37
+
38
+ def mime_type
39
+ MIME::Types.type_for(path.to_s).first
40
+ end
41
+
42
+ def size
43
+ exists? ? File.size(path) : nil
44
+ end
45
+
46
+ def width
47
+ dimensions[0]
48
+ end
49
+
50
+ def height
51
+ dimensions[1]
52
+ end
53
+
54
+ def data
55
+ @data ||= Data.manage({
56
+ "width" => width,
57
+ "height" => height
58
+ }.compact)
59
+ end
60
+
61
+ def body
62
+ File.binread(path)
63
+ end
64
+
65
+ def exists?
66
+ path.exist?
67
+ end
68
+
69
+ def inspect
70
+ "#<#{self.class}:0x#{object_id.to_s(16)} path=#{path.to_s.inspect}>"
71
+ end
72
+
73
+ private
74
+
75
+ def dimensions
76
+ @dimensions ||= begin
77
+ return [nil, nil] unless exists?
78
+ FastImage.size(path.to_s) || [nil, nil]
79
+ rescue
80
+ [nil, nil]
81
+ end
82
+ end
83
+ end
84
+ end
@@ -1,3 +1,5 @@
1
+ require "forwardable"
2
+
1
3
  module Sitepress
2
4
  # Resource nodes give resources their parent/sibling/child relationships. The relationship are determined
3
5
  # by the `request_path` given to an asset when its added to a node. Given the `request_path` `/foo/bar/biz/buz.html`,
@@ -96,6 +98,10 @@ module Sitepress
96
98
  "<#{self.class}: name=#{name.inspect}, formats=#{formats.inspect}, children=#{children.map(&:name).inspect}, resource_request_paths=#{resources.map(&:request_path)}>"
97
99
  end
98
100
 
101
+ def <<(mountable)
102
+ mountable.mount(self)
103
+ end
104
+
99
105
  def dig(*args)
100
106
  head, *tail = args
101
107
  if (head.nil? or head.empty? or head == default_name) and tail.empty?
@@ -3,16 +3,35 @@ require "forwardable"
3
3
  require "fileutils"
4
4
 
5
5
  module Sitepress
6
- # Represents a file on a web server that may be parsed to extract
6
+ # Represents a page on a website - a file that may be parsed to extract
7
7
  # metadata or be renderable via a template. Multiple resources
8
- # may point to the same asset. Properties of an asset should be mutable.
8
+ # may point to the same page. Properties of a page should be mutable.
9
9
  # The Resource object is immutable and may be modified by the Resources proxy.
10
- class Asset
10
+ class Page
11
11
  # If we can't resolve a mime type for the resource, we'll fall
12
12
  # back to this binary octet-stream type so the client can download
13
13
  # the resource and figure out what to do with it.
14
14
  DEFAULT_MIME_TYPE = MIME::Types["application/octet-stream"].first
15
15
 
16
+ # MIME types that Page can handle - text-based content that may have frontmatter
17
+ MIME_TYPES = %w[
18
+ text/html
19
+ text/plain
20
+ text/markdown
21
+ text/x-web-markdown
22
+ text/css
23
+ text/javascript
24
+ application/json
25
+ application/xml
26
+ text/xml
27
+ image/svg+xml
28
+ text/x-haml
29
+ ].freeze
30
+
31
+ def self.mime_types
32
+ MIME_TYPES
33
+ end
34
+
16
35
  # Parsers can be swapped out to deal with different types of resources, like Notion
17
36
  # documents, JSON, exif data on images, etc.
18
37
  DEFAULT_PARSER = Parsers::Frontmatter
@@ -44,9 +63,19 @@ module Sitepress
44
63
  @body ||= exists? ? parse_error { parser.body } : nil
45
64
  end
46
65
 
66
+ # Returns the line number where the body starts in the original file.
67
+ # Used to adjust error line numbers when frontmatter is present.
68
+ def body_line_offset
69
+ exists? ? parser.body_line_offset : 1
70
+ end
71
+
47
72
  # Treat resources with the same request path as equal.
48
- def ==(asset)
49
- path == asset.path
73
+ def ==(other)
74
+ path == other.path
75
+ end
76
+
77
+ def inspect
78
+ "#<#{self.class}:0x#{object_id.to_s(16)} path=#{path.to_s.inspect}>"
50
79
  end
51
80
 
52
81
  def mime_type
@@ -60,9 +89,11 @@ module Sitepress
60
89
  !!handler
61
90
  end
62
91
 
63
- # Mmm.... that's the smell of cache busting, which means the hiearchy of this is wrong.
92
+ # When changing the parser, clear all cached parsed data.
64
93
  def parser=(parser_klass)
65
94
  @parser = nil
95
+ @data = nil
96
+ @body = nil
66
97
  @parser_klass = parser_klass
67
98
  end
68
99
 
@@ -86,11 +117,17 @@ module Sitepress
86
117
  @parser_klass::Renderer.new(data: data, body: body)
87
118
  end
88
119
 
120
+ # Renders the page in a view context. This is part of the Renderable protocol
121
+ # that allows any object to be used as a resource source.
122
+ def render_in(view_context)
123
+ view_context.render inline: body, type: handler
124
+ end
125
+
89
126
  private
90
127
  def parse_error(&parse)
91
128
  parse.call
92
129
  rescue StandardError => e
93
- raise ParseError.new("Error parsing asset at #{path.to_s}: #{e}")
130
+ raise ParseError, "Error parsing #{path.expand_path}: #{e.class} - #{e.message}"
94
131
  end
95
132
 
96
133
  def parser
@@ -104,4 +141,7 @@ module Sitepress
104
141
  MIME::Types.type_for(format_extension).first if format_extension
105
142
  end
106
143
  end
144
+
145
+ # Backwards compatibility
146
+ Asset = Page
107
147
  end
@@ -10,6 +10,12 @@ module Sitepress
10
10
  @body = source
11
11
  @data = {}
12
12
  end
13
+
14
+ # Returns the line number where the body starts in the original file.
15
+ # Subclasses should override this if they strip content from the beginning.
16
+ def body_line_offset
17
+ 1
18
+ end
13
19
  end
14
20
  end
15
21
  end
@@ -14,12 +14,7 @@ module Sitepress
14
14
  end
15
15
 
16
16
  def dump_yaml(data)
17
- if YAML.respond_to? :safe_dump
18
- YAML.safe_dump data, permitted_classes: Frontmatter.permitted_classes
19
- else
20
- # Live dangerously, lol
21
- YAML.dump data
22
- end
17
+ YAML.safe_dump data, permitted_classes: Frontmatter.permitted_classes
23
18
  end
24
19
 
25
20
  def render
@@ -46,7 +41,13 @@ module Sitepress
46
41
  PATTERN = /\A(#{DELIMITER}#{NEWLINE}(.+?)#{NEWLINE}#{DELIMITER}#{NEWLINE}*)?(.+)\Z/m
47
42
 
48
43
  def initialize(content)
49
- _, @data, @body = content.match(PATTERN).captures
44
+ @frontmatter_block, @data, @body = content.match(PATTERN).captures
45
+ end
46
+
47
+ # Returns the line number where the body starts in the original file.
48
+ def body_line_offset
49
+ return 1 unless @frontmatter_block
50
+ @frontmatter_block.count("\n") + 1
50
51
  end
51
52
 
52
53
  def data
@@ -54,12 +55,7 @@ module Sitepress
54
55
  end
55
56
 
56
57
  def load_yaml(data)
57
- if YAML.respond_to? :safe_load
58
- YAML.safe_load data, permitted_classes: self.class.permitted_classes
59
- else
60
- # Live dangerously, lol
61
- YAML.load data
62
- end
58
+ YAML.safe_load data, permitted_classes: self.class.permitted_classes
63
59
  end
64
60
 
65
61
  class << self
@@ -1,4 +1,5 @@
1
1
  require "yaml"
2
+ require "strscan"
2
3
 
3
4
  module Sitepress
4
5
  module Parsers
@@ -19,10 +20,17 @@ module Sitepress
19
20
  @raw_data.append scanner.captures
20
21
  end
21
22
  scanner.scan(/\n/)
23
+ # Track where body starts for line number offset
24
+ @header_content = content[0, scanner.pos]
22
25
  # Parse body
23
26
  @body = scanner.rest
24
27
  end
25
28
 
29
+ # Returns the line number where the body starts in the original file.
30
+ def body_line_offset
31
+ @header_content.count("\n") + 1
32
+ end
33
+
26
34
  def data
27
35
  Hash[@raw_data.prepend([TITLE_KEY, @title])]
28
36
  end
@@ -23,14 +23,6 @@ module Sitepress
23
23
  action_view_template_handlers_extensions || HANDLER_EXTENSIONS
24
24
  end
25
25
 
26
- # I tried to hook this into Rails engines in the `config.after_initialize` block,
27
- # but the way template handlers register their extensions is across the board.
28
- #
29
- # config.after_initialize do
30
- # Sitepress::Path.handler_extensions = ActionView::Template::Handlers.method(:extensions)
31
- # ends
32
- #
33
- # I couldn't get that working, instead I do this check to find the handlers.
34
26
  def action_view_template_handlers_extensions
35
27
  ActionView::Template::Handlers.extensions if defined?(ActionView::Template::Handlers)
36
28
  end
@@ -4,23 +4,44 @@ module Sitepress
4
4
  # Represents the request path of an asset. There may be multiple
5
5
  # resources that point to the same asset. Resources are immutable
6
6
  # and may be altered by the resource proxy.
7
+ #
8
+ # The source can be any object that implements the Renderable protocol:
9
+ # - #data - returns a Hash of metadata
10
+ # - #render_in(view_context) - renders the content
7
11
  class Resource
8
12
  extend Forwardable
9
- def_delegators :asset, :body, :data, :renderable?
13
+ def_delegators :source, :body
10
14
 
11
- attr_reader :node, :asset
15
+ attr_reader :node, :source
16
+ alias :asset :source # Backwards compatibility
17
+
18
+ # Check if the source implements the data protocol.
19
+ def has_data?
20
+ source.respond_to?(:data)
21
+ end
22
+
23
+ # Check if the source implements the render_in protocol.
24
+ def renderable?
25
+ source.respond_to?(:render_in)
26
+ end
27
+
28
+ # Returns metadata from the source, or an empty hash if not available.
29
+ def data
30
+ has_data? ? source.data : {}
31
+ end
12
32
 
13
33
  attr_accessor :format, :mime_type, :handler
14
34
 
15
35
  # Default scope for querying parent/child/sibling resources.
16
36
  DEFAULT_FILTER_SCOPE = :same
17
37
 
18
- def initialize(asset:, node:, format: nil, mime_type: nil, handler: nil)
19
- @asset = asset
38
+ def initialize(asset: nil, source: nil, node:, format: nil, mime_type: nil, handler: nil)
39
+ @source = source || asset
40
+ raise ArgumentError, "Either asset: or source: must be provided" unless @source
20
41
  @node = node
21
- @format = format || asset.format
22
- @mime_type = mime_type || asset.mime_type
23
- @handler = handler || asset.handler
42
+ @format = format || @source.format
43
+ @mime_type = mime_type || @source.mime_type
44
+ @handler = handler || source_handler
24
45
  end
25
46
 
26
47
  def request_path
@@ -71,7 +92,7 @@ module Sitepress
71
92
  # Clones should be initialized with a nil node. Initializing with a node would mean that multiple resources
72
93
  # are pointing to the same node, which shouldn't be possible.
73
94
  def clone
74
- self.class.new(asset: @asset, node: nil, format: @format, mime_type: @mime_type, handler: @handler)
95
+ self.class.new(source: @source, node: nil, format: @format, mime_type: @mime_type, handler: @handler)
75
96
  end
76
97
 
77
98
  # Removes the resource from the node's resources list.
@@ -80,7 +101,7 @@ module Sitepress
80
101
  end
81
102
 
82
103
  def inspect
83
- "<#{self.class}:#{object_id} request_path=#{request_path.inspect} asset_path=#{asset.path.to_s.inspect}>"
104
+ "#<#{self.class}:0x#{object_id.to_s(16)} request_path=#{request_path.inspect} source=#{source.inspect}>"
84
105
  end
85
106
 
86
107
  def parent(**args)
@@ -109,7 +130,7 @@ module Sitepress
109
130
  end
110
131
 
111
132
  def render_in(view_context)
112
- view_context.render inline: body, type: handler
133
+ renderable? ? source.render_in(view_context) : nil
113
134
  end
114
135
 
115
136
  private
@@ -135,6 +156,10 @@ module Sitepress
135
156
  end
136
157
  end
137
158
 
159
+ def source_handler
160
+ @source.handler if @source.respond_to?(:handler)
161
+ end
162
+
138
163
  # Deals with situations, particularly in the root node and other "index" nodes, for the `request_path`
139
164
  def request_filename
140
165
  if node.root? and node.default_format == format
@@ -1,3 +1,6 @@
1
+ require "forwardable"
2
+ require "set"
3
+
1
4
  module Sitepress
2
5
  # Flattens a tree of Sitepress::Node and Sitepress:Resource classes into a collection of
3
6
  # resources that can be quickly globbed, queried, or accessed.
@@ -17,8 +20,8 @@ module Sitepress
17
20
  end
18
21
 
19
22
  def glob(pattern)
20
- paths = Dir.glob root_path.join(pattern)
21
- resources.select { |r| paths.include? r.asset.path.to_s }
23
+ paths = Dir.glob(root_path.join(pattern)).to_set
24
+ resources.select { |r| paths.include?(r.asset.path.to_s) }
22
25
  end
23
26
 
24
27
  def get(request_path)
@@ -1,5 +1,3 @@
1
- require "forwardable"
2
-
3
1
  module Sitepress
4
2
  # Processes a collection of resources
5
3
  class ResourcesPipeline < Array
@@ -19,18 +19,18 @@ module Sitepress
19
19
  self.root_path = root_path
20
20
  end
21
21
 
22
- # A tree representation of the resourecs wthin the site. The root is a node that's
22
+ # A tree representation of the resources within the site. The root is a node that's
23
23
  # processed by the `resources_pipeline`.
24
24
  def root
25
25
  @root ||= Node.new.tap do |root|
26
- asset_node_mapper(root).map
26
+ root << asset_node_mapper
27
27
  resources_pipeline.process root
28
28
  end
29
29
  end
30
30
 
31
31
  # Maps a path of directories and files into the root node.
32
- def asset_node_mapper(root_node)
33
- AssetNodeMapper.new(path: pages_path, node: root_node)
32
+ def asset_node_mapper
33
+ Directory.new(pages_path)
34
34
  end
35
35
 
36
36
  # Returns a list of all the resources within #root.
@@ -0,0 +1,47 @@
1
+ require "mime/types"
2
+
3
+ module Sitepress
4
+ # A source for static files that are served as-is without processing.
5
+ # Used as a fallback for files that don't match Image or Page MIME types.
6
+ #
7
+ # Example:
8
+ # static = Static.new(path: "fonts/roboto.woff2")
9
+ # static.mime_type # => #<MIME::Type font/woff2>
10
+ # static.body # => binary content
11
+ #
12
+ class Static
13
+ attr_reader :path
14
+
15
+ def initialize(path:)
16
+ @path = Pathname.new(path)
17
+ end
18
+
19
+ def node_name
20
+ path.basename(".*").to_s.split(".").first
21
+ end
22
+
23
+ def format
24
+ path.extname.delete(".").to_sym
25
+ end
26
+
27
+ def mime_type
28
+ MIME::Types.type_for(path.to_s).first
29
+ end
30
+
31
+ def body
32
+ File.binread(path)
33
+ end
34
+
35
+ def data
36
+ @data ||= Data.manage({})
37
+ end
38
+
39
+ def exists?
40
+ path.exist?
41
+ end
42
+
43
+ def inspect
44
+ "#<#{self.class}:0x#{object_id.to_s(16)} path=#{path.to_s.inspect}>"
45
+ end
46
+ end
47
+ end
@@ -1,3 +1,3 @@
1
1
  module Sitepress
2
- VERSION = "4.1.1".freeze
2
+ VERSION = "5.0.0.beta".freeze
3
3
  end
@@ -4,17 +4,23 @@ module Sitepress
4
4
  # Errors raised by Sitepress
5
5
  Error = Class.new(StandardError)
6
6
 
7
+ # Raised when an asset fails to parse (e.g., invalid YAML frontmatter)
8
+ ParseError = Class.new(Error)
9
+
7
10
  # Raised by Resources if a path is added that's not a valid path.
8
11
  InvalidRequestPathError = Class.new(RuntimeError)
9
12
 
10
13
  # Raised by Resources if a path is already in its index
11
14
  ExistingRequestPathError = Class.new(InvalidRequestPathError)
12
15
 
13
- autoload :Asset, "sitepress/asset"
14
- autoload :AssetNodeMapper, "sitepress/asset_node_mapper"
16
+ autoload :Asset, "sitepress/page" # Backwards compatibility
17
+ autoload :AssetNodeMapper, "sitepress/directory" # Backwards compatibility
15
18
  autoload :AssetPaths, "sitepress/asset_paths"
19
+ autoload :Directory, "sitepress/directory"
16
20
  autoload :Data, "sitepress/data"
21
+ autoload :Image, "sitepress/image"
17
22
  autoload :Node, "sitepress/node"
23
+ autoload :Page, "sitepress/page"
18
24
  autoload :Path, "sitepress/path"
19
25
  autoload :Parsers, "sitepress/parsers"
20
26
  autoload :Resource, "sitepress/resource"
@@ -22,4 +28,5 @@ module Sitepress
22
28
  autoload :ResourceIndexer, "sitepress/resource_indexer"
23
29
  autoload :ResourcesPipeline, "sitepress/resources_pipeline"
24
30
  autoload :Site, "sitepress/site"
31
+ autoload :Static, "sitepress/static"
25
32
  end
@@ -26,4 +26,5 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency "rspec", "~> 3.0"
27
27
 
28
28
  spec.add_runtime_dependency "mime-types", ">= 2.99"
29
+ spec.add_runtime_dependency "fastimage", "~> 2.0"
29
30
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sitepress-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.1
4
+ version: 5.0.0.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brad Gessler
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-11-17 00:00:00.000000000 Z
10
+ date: 2026-02-20 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: bundler
@@ -65,6 +65,20 @@ dependencies:
65
65
  - - ">="
66
66
  - !ruby/object:Gem::Version
67
67
  version: '2.99'
68
+ - !ruby/object:Gem::Dependency
69
+ name: fastimage
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '2.0'
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '2.0'
68
82
  email:
69
83
  - bradgessler@gmail.com
70
84
  executables: []
@@ -72,13 +86,14 @@ extensions: []
72
86
  extra_rdoc_files: []
73
87
  files:
74
88
  - lib/sitepress-core.rb
75
- - lib/sitepress/asset.rb
76
- - lib/sitepress/asset_node_mapper.rb
77
89
  - lib/sitepress/asset_paths.rb
78
90
  - lib/sitepress/data.rb
91
+ - lib/sitepress/directory.rb
79
92
  - lib/sitepress/extensions/layouts.rb
80
93
  - lib/sitepress/extensions/proc_manipulator.rb
94
+ - lib/sitepress/image.rb
81
95
  - lib/sitepress/node.rb
96
+ - lib/sitepress/page.rb
82
97
  - lib/sitepress/parsers.rb
83
98
  - lib/sitepress/parsers/base.rb
84
99
  - lib/sitepress/parsers/frontmatter.rb
@@ -89,6 +104,7 @@ files:
89
104
  - lib/sitepress/resources.rb
90
105
  - lib/sitepress/resources_pipeline.rb
91
106
  - lib/sitepress/site.rb
107
+ - lib/sitepress/static.rb
92
108
  - lib/sitepress/version.rb
93
109
  - sitepress-core.gemspec
94
110
  homepage: https://sitepress.cc/
@@ -1,45 +0,0 @@
1
- module Sitepress
2
- # Maps a tree of Directory and Asset objects in a a tree of nodes that
3
- # format the navigational structure of a website. You can override this
4
- # this in a site to deal with different file systems. For example, Notion
5
- # has a completely different file structure for its content than Rails, so
6
- # we could extend this class to properly map those differences into a tree
7
- # of nodes.
8
- class AssetNodeMapper
9
- attr_reader :node, :asset_paths
10
-
11
- def initialize(path:, node:)
12
- @asset_paths = AssetPaths.new(path: path)
13
- @node = node
14
- end
15
-
16
- # Mounts the source files from the path to the given node.
17
- def map
18
- asset_paths.each do |path|
19
- if path.directory?
20
- process_directory path
21
- else
22
- process_asset path
23
- end
24
- end
25
- end
26
-
27
- protected
28
-
29
- def process_directory(path)
30
- node_name = File.basename path
31
- node_mapper path: path, node: node.child(node_name)
32
- end
33
-
34
- def process_asset(path)
35
- asset = Asset.new(path: path)
36
- node.child(asset.node_name).resources.add_asset(asset, format: asset.format)
37
- end
38
-
39
- private
40
-
41
- def node_mapper(*args, **kwargs)
42
- self.class.new(*args, **kwargs).map
43
- end
44
- end
45
- end