contentfs 0.1.0 → 0.4.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: b815f957fcccb235ddec7a7cd90ae7392727a949e50883bbcf9425c4904b5fba
4
- data.tar.gz: 0e20ede1a87ef3fa34f7755740489322039f760580406b44d35914fb6103aff2
3
+ metadata.gz: 9e66ff05acd68a19366aae10bfc7c25e0a97c00a498f4654c20e825f4e84a7a2
4
+ data.tar.gz: 5da2c74e38cc0a0a05fe3fa942d1c1855bebf41fb8e2e643630d490e2c8241c0
5
5
  SHA512:
6
- metadata.gz: 36c32a237713fdd88a28ce5c6fe0770c0aefa0275e5d350f31a56a363976d83c72428ea6ab89e79645d1c28c0fbfc681704c0dd7856069efcbc7034546398168
7
- data.tar.gz: a7abf1c49c7cdaadcdb855ed1a5965eb4f3f0623fa63f7a86b03ac72c1f0f2e05bc427d06c84dfcab75aa8323df93e983aba043ffb1c39594e0a1753cd7acfbc
6
+ metadata.gz: 5a3a49083b8935a1807b74166430cd3e18a130ba04e948703047a323c5de405c491482bd155fe6ed2f84ac4d1a040fb0e66aee2d76f10956ddb86b84385727f1
7
+ data.tar.gz: 7d1ddf1d6454d2a2457bbc4a3bf771b56bcf024f19244edb744f92b9953e81f0fe0fc72a3a08e7e206740a58015858d103fffe01696e31710a55d4a803a07838
data/CHANGELOG.md CHANGED
@@ -1,6 +1,36 @@
1
- ## v0.1.0
1
+ ## [v0.4.0](https://github.com/metabahn/contentfs/releases/tag/v0.4.0)
2
+
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*
10
+
11
+ * `chg` [#8](https://github.com/metabahn/contentfs/pull/8) Load database content from _content to avoid collisions ([bryanp](https://github.com/bryanp))
12
+
13
+ ## v0.2.1
14
+
2
15
  *unreleased*
3
16
 
17
+ * `fix` [#7](https://github.com/metabahn/contentfs/pull/7) Order content and databases by prefix or slug ([bryanp](https://github.com/bryanp))
18
+
19
+ ## [v0.2.0](https://github.com/metabahn/contentfs/releases/tag/v0.2.0)
20
+
21
+ *released on 2020-11-14*
22
+
23
+ * `add` [#6](https://github.com/metabahn/contentfs/pull/6) Expose database metadata ([bryanp](https://github.com/bryanp))
24
+
25
+ ## [v0.1.1](https://github.com/metabahn/contentfs/releases/tag/v0.1.1)
26
+
27
+ *released on 2020-11-13*
28
+
29
+ * `fix` [#5](https://github.com/metabahn/contentfs/pull/5) Remove front-matter from content ([bryanp](https://github.com/bryanp))
30
+
31
+ ## [v0.1.0](https://github.com/metabahn/contentfs/releases/tag/v0.1.0)
32
+
33
+ *released on 2020-11-12*
4
34
 
5
35
  * `add` [#4](https://github.com/metabahn/contentfs/pull/4) Expose namespaces for databases and content ([bryanp](https://github.com/bryanp))
6
36
  * `add` [#3](https://github.com/metabahn/contentfs/pull/3) Introduce `Database#nested` for iterating over databases ([bryanp](https://github.com/bryanp))
@@ -8,8 +38,8 @@
8
38
  * `add` [#1](https://github.com/metabahn/contentfs/pull/1) Introduce `Database#find` for safer traversal ([bryanp](https://github.com/bryanp))
9
39
 
10
40
  ## [v0.0.0](https://github.com/metabahn/contentfs/releases/tag/v0.0.0)
11
- *released on 2020-11-11*
12
41
 
42
+ *released on 2020-11-11*
13
43
 
14
44
  * Initial release.
15
45
 
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,26 +12,30 @@ 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
- @content = path.read
33
- @metadata = metadata.merge(parse_metadata(@content))
34
33
  @namespace = namespace.dup << @slug
34
+ @database = database
35
+
36
+ content = path.read
37
+ @metadata = metadata.merge(parse_metadata(content))
38
+ @content = content.gsub(FRONT_MATTER_REGEXP, "")
35
39
  end
36
40
 
37
41
  def to_s
@@ -39,8 +43,16 @@ module ContentFS
39
43
  end
40
44
 
41
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
+
42
54
  if @format && (renderer = Renderers.resolve(@format))
43
- renderer.render(@content)
55
+ renderer.render(working_content)
44
56
  else
45
57
  to_s
46
58
  end
@@ -11,23 +11,22 @@ 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
 
19
19
  METADATA_FILE = "_metadata.yml"
20
20
 
21
- attr_reader :prefix, :slug, :namespace
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
- @children = {}
29
- @nested = {}
30
28
  @namespace = namespace.dup
29
+ @parent = parent
31
30
 
32
31
  unless root
33
32
  @slug = Slug.build(remainder)
@@ -36,28 +35,54 @@ module ContentFS
36
35
 
37
36
  metadata_path = path.join(METADATA_FILE)
38
37
 
39
- metadata = if metadata_path.exist?
38
+ @metadata = if metadata_path.exist?
40
39
  YAML.safe_load(metadata_path.read).to_h
41
40
  else
42
41
  {}
43
42
  end
44
43
 
44
+ content_path = path.join.glob("_content.*")[0]
45
+
46
+ @content = if content_path&.exist?
47
+ Content.load(content_path, database: self, metadata: @metadata, namespace: @namespace)
48
+ end
49
+
50
+ children, nested, includes = {}, {}, {}
45
51
  Pathname.new(path).glob("*") do |path|
46
- next if path.basename.to_s.start_with?("_")
52
+ underscored = path.basename.to_s.start_with?("_")
53
+ next if underscored && path.directory?
47
54
 
48
55
  if path.directory?
49
- database = Database.load(path, namespace: @namespace, root: false)
50
- @nested[database.slug] = database
56
+ database = Database.load(path, parent: self, namespace: @namespace, root: false)
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
51
62
  else
52
- content = Content.load(path, metadata: metadata, namespace: @namespace)
63
+ content = Content.load(path, database: self, metadata: @metadata, namespace: @namespace)
53
64
 
54
- if content.slug == :content
55
- @content = content
56
- else
57
- @children[content.slug] = content
58
- end
65
+ children[content.slug] = content
59
66
  end
60
67
  end
68
+
69
+ @children = Hash[
70
+ children.sort_by { |key, content|
71
+ (content.prefix || content.slug).to_s
72
+ }
73
+ ]
74
+
75
+ @nested = Hash[
76
+ nested.sort_by { |key, database|
77
+ (database.prefix || database.slug).to_s
78
+ }
79
+ ]
80
+
81
+ @includes = Hash[
82
+ includes.sort_by { |key, content|
83
+ (content.prefix || content.slug).to_s
84
+ }
85
+ ]
61
86
  end
62
87
 
63
88
  def content
@@ -100,6 +125,35 @@ module ContentFS
100
125
  end
101
126
  end
102
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
+
103
157
  def to_s
104
158
  @content&.to_s.to_s
105
159
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ContentFS
4
- VERSION = "0.1.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.1.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-13 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.