contentfs 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5386e4d1a1ef23527ec457ecb544d4d36d02e44811fe81f87db93f4188d82145
4
- data.tar.gz: f44614daf6d97aabd4d83a0e2339dd8d20e19d742b8b8403c37fc2967dd40925
3
+ metadata.gz: 9e66ff05acd68a19366aae10bfc7c25e0a97c00a498f4654c20e825f4e84a7a2
4
+ data.tar.gz: 5da2c74e38cc0a0a05fe3fa942d1c1855bebf41fb8e2e643630d490e2c8241c0
5
5
  SHA512:
6
- metadata.gz: 39ee593b9c158d2093d5a8bc59a8d8510adb8a206d4b786a0465347e79f12323806765be999be8ad7fd14bccb4e32134696c1f851fa466a1a515d3b44d7ecc63
7
- data.tar.gz: f1ab2b7a9cc994b5d91cef392fa8d4a4c1bedaac69428ceb9552143b7f969391ec32a16ae1240c66da616a80440945bfae9f8a30e010bcd47f2f36f7aa89e3ef
6
+ metadata.gz: 5a3a49083b8935a1807b74166430cd3e18a130ba04e948703047a323c5de405c491482bd155fe6ed2f84ac4d1a040fb0e66aee2d76f10956ddb86b84385727f1
7
+ data.tar.gz: 7d1ddf1d6454d2a2457bbc4a3bf771b56bcf024f19244edb744f92b9953e81f0fe0fc72a3a08e7e206740a58015858d103fffe01696e31710a55d4a803a07838
data/CHANGELOG.md CHANGED
@@ -1,6 +1,12 @@
1
- ## v0.3.0
1
+ ## [v0.4.0](https://github.com/metabahn/contentfs/releases/tag/v0.4.0)
2
2
 
3
- *unreleased*
3
+ *released on 2021-04-01*
4
+
5
+ * `add` [#9](https://github.com/metabahn/contentfs/pull/9) Includes ([bryanp](https://github.com/bryanp))
6
+
7
+ ## [v0.3.0](https://github.com/metabahn/contentfs/releases/tag/v0.3.0)
8
+
9
+ *released on 2020-11-18*
4
10
 
5
11
  * `chg` [#8](https://github.com/metabahn/contentfs/pull/8) Load database content from _content to avoid collisions ([bryanp](https://github.com/bryanp))
6
12
 
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  This software is licensed under the MIT License.
2
2
 
3
- Copyright 2020 Metabahn.
3
+ Copyright 2020-2021 Metabahn.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a
6
6
  copy of this software and associated documentation files (the
@@ -12,24 +12,26 @@ module ContentFS
12
12
  #
13
13
  class Content
14
14
  class << self
15
- def load(path, metadata: {}, namespace: [])
16
- new(path: path, metadata: metadata, namespace: namespace)
15
+ def load(path, database:, metadata: {}, namespace: [])
16
+ new(path: path, database: database, metadata: metadata, namespace: namespace)
17
17
  end
18
18
  end
19
19
 
20
20
  FRONT_MATTER_REGEXP = /\A---\s*\n(.*?\n?)^---\s*$\n?/m
21
+ INCLUDE_REGEXP = /<!-- @include\s*([a-zA-Z0-9\-_\/.]*) -->/
21
22
 
22
23
  attr_reader :format, :prefix, :slug, :metadata, :namespace
23
24
 
24
- def initialize(path:, metadata: {}, namespace: [])
25
+ def initialize(path:, database:, metadata: {}, namespace: [])
25
26
  path = Pathname.new(path)
26
27
  extname = path.extname
27
28
  name = path.basename(extname)
28
29
  prefix, remainder = Prefix.build(name)
29
30
  @prefix = prefix
30
- @format = extname.to_s[1..-1]&.to_sym
31
+ @format = extname.to_s[1..]&.to_sym
31
32
  @slug = Slug.build(remainder)
32
33
  @namespace = namespace.dup << @slug
34
+ @database = database
33
35
 
34
36
  content = path.read
35
37
  @metadata = metadata.merge(parse_metadata(content))
@@ -41,8 +43,16 @@ module ContentFS
41
43
  end
42
44
 
43
45
  def render
46
+ working_content = @content.dup
47
+
48
+ @content.scan(INCLUDE_REGEXP).each do |match|
49
+ if (include = @database.find_include(match[0]))
50
+ working_content.gsub!($~.to_s, include.render)
51
+ end
52
+ end
53
+
44
54
  if @format && (renderer = Renderers.resolve(@format))
45
- renderer.render(@content)
55
+ renderer.render(working_content)
46
56
  else
47
57
  to_s
48
58
  end
@@ -11,8 +11,8 @@ module ContentFS
11
11
  #
12
12
  class Database
13
13
  class << self
14
- def load(path, namespace: [], root: true)
15
- new(path: path, namespace: namespace, root: root)
14
+ def load(path, parent: nil, namespace: [], root: true)
15
+ new(path: path, parent: parent, namespace: namespace, root: root)
16
16
  end
17
17
  end
18
18
 
@@ -20,12 +20,13 @@ module ContentFS
20
20
 
21
21
  attr_reader :prefix, :slug, :namespace, :metadata
22
22
 
23
- def initialize(path:, namespace: [], root: false)
23
+ def initialize(path:, parent: nil, namespace: [], root: false)
24
24
  path = Pathname.new(path)
25
25
  name = path.basename(path.extname)
26
26
  prefix, remainder = Prefix.build(name)
27
27
  @prefix = prefix
28
28
  @namespace = namespace.dup
29
+ @parent = parent
29
30
 
30
31
  unless root
31
32
  @slug = Slug.build(remainder)
@@ -43,18 +44,23 @@ module ContentFS
43
44
  content_path = path.join.glob("_content.*")[0]
44
45
 
45
46
  @content = if content_path&.exist?
46
- Content.load(content_path, metadata: @metadata, namespace: @namespace)
47
+ Content.load(content_path, database: self, metadata: @metadata, namespace: @namespace)
47
48
  end
48
49
 
49
- children, nested = {}, {}
50
+ children, nested, includes = {}, {}, {}
50
51
  Pathname.new(path).glob("*") do |path|
51
- next if path.basename.to_s.start_with?("_")
52
+ underscored = path.basename.to_s.start_with?("_")
53
+ next if underscored && path.directory?
52
54
 
53
55
  if path.directory?
54
- database = Database.load(path, namespace: @namespace, root: false)
56
+ database = Database.load(path, parent: self, namespace: @namespace, root: false)
55
57
  nested[database.slug] = database
58
+ elsif underscored
59
+ content = Content.load(path, database: self, metadata: @metadata, namespace: @namespace)
60
+
61
+ includes[content.slug.to_s[1..].to_sym] = content
56
62
  else
57
- content = Content.load(path, metadata: @metadata, namespace: @namespace)
63
+ content = Content.load(path, database: self, metadata: @metadata, namespace: @namespace)
58
64
 
59
65
  children[content.slug] = content
60
66
  end
@@ -71,6 +77,12 @@ module ContentFS
71
77
  (database.prefix || database.slug).to_s
72
78
  }
73
79
  ]
80
+
81
+ @includes = Hash[
82
+ includes.sort_by { |key, content|
83
+ (content.prefix || content.slug).to_s
84
+ }
85
+ ]
74
86
  end
75
87
 
76
88
  def content
@@ -113,6 +125,35 @@ module ContentFS
113
125
  end
114
126
  end
115
127
 
128
+ def find_include(path)
129
+ @includes[path.to_sym] || find_child_include(path) || find_parent_include(path) || find_include_from_toplevel(path)
130
+ end
131
+
132
+ def toplevel
133
+ @parent ? @parent.toplevel : self
134
+ end
135
+
136
+ private def find_child_include(path)
137
+ return unless path.include?("/")
138
+
139
+ path_parts = path.split("/", 2)
140
+ @nested[path_parts[0].to_sym]&.find_include(path_parts[1])
141
+ end
142
+
143
+ private def find_parent_include(path)
144
+ return if @parent.nil?
145
+ return unless path.start_with?("../")
146
+
147
+ path_parts = path.split("../", 2)
148
+ @parent.find_include(path_parts[1])
149
+ end
150
+
151
+ private def find_include_from_toplevel(path)
152
+ return if @parent.nil?
153
+
154
+ toplevel.find_include(path)
155
+ end
156
+
116
157
  def to_s
117
158
  @content&.to_s.to_s
118
159
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ContentFS
4
- VERSION = "0.3.0"
4
+ VERSION = "0.4.0"
5
5
 
6
6
  def self.version
7
7
  VERSION
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: contentfs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bryan Powell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-18 00:00:00.000000000 Z
11
+ date: 2021-04-01 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A structured content file system.
14
14
  email: bryan@metabahn.com
@@ -47,7 +47,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
47
47
  - !ruby/object:Gem::Version
48
48
  version: '0'
49
49
  requirements: []
50
- rubygems_version: 3.1.2
50
+ rubygems_version: 3.2.4
51
51
  signing_key:
52
52
  specification_version: 4
53
53
  summary: A structured content file system.