raindeer 0.5.0 → 0.7.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: 10abc837f7a79dd6e8807ab756f5d393324ef1643dc7eacfc53fdd09246e5d97
4
- data.tar.gz: 15eb9638281737ad60f8ce07dd9164f8584ec5ac8a66b0d5f304c734f13155f0
3
+ metadata.gz: 1911af310e0e12743cd151c8d0434b247d959385ea04329a40287538199b0407
4
+ data.tar.gz: 84320dbf6de9d25dd6c9c3315f51abfddeb2e21d62ddd6e99e8ff754ba252ba4
5
5
  SHA512:
6
- metadata.gz: 27d14ec70fdd565fa5d62833f05672762bce3e050a482b6748d99b524892b473b42cda5658b3aa22dc459fcd3230614e724928d01de5e1d138031ee0a6f4151e
7
- data.tar.gz: 07761ecc57e9660c719793226e63f6be7ba4d795e660647d8d9540b16b53a857f5e33e27e8d3aa435b2775d2a4222b8df17220008036f77cd64637fb8239d8b4
6
+ metadata.gz: 7341996eb059d5dc1f7fb6075c2ffeb866efc6a68fc4a69142c321be325bdc5e15dad955a67d24b39b185dbbe2d6670466fddaf802ae8b43cb448cd0258fe33e
7
+ data.tar.gz: db80a6183bde1082b49cb230252f43ca9a5ff97eea0c5effda469ae0c09f17a4f2be9f16d8a9b9041388fb53eeebeda1b691dac8ed37a47459e70ef21f30c890
data/bin/rain ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Call "rain" to access the CLI loaded on your $PATH by Bundler.
4
+ # Uncomment the line below and call "bin/rain" to load local gems from your Gemfile in development.
5
+ # Comment this line out when running "bundle exec rake install".
6
+ # require 'bundler/setup'
7
+
8
+ require_relative '../lib/raindeer/cli'
9
+
10
+ Rain::CLI.run(ARGV)
data/lib/cli/cli.rb ADDED
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'trees'
4
+ require_relative 'static/static'
5
+
6
+ module Rain
7
+ module CLI
8
+ extend Trees
9
+
10
+ line('new :app_name') do |app_name|
11
+ execute { 'TODO' }
12
+ end
13
+
14
+ line('server') do
15
+ execute { system('bin/server') }
16
+ end
17
+
18
+ line('static') do
19
+ summary { 'Static site generation' }
20
+
21
+ line('build') do
22
+ execute { Static.build(application_path: Dir.pwd) }
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'antlers'
4
+ require 'lowload'
5
+
6
+ module Rain
7
+ module CLI
8
+ module Static
9
+ extend self
10
+
11
+ def build(application_path:)
12
+ metadata = LowLoad.dirload(File.expand_path('app', application_path))
13
+ # TODO: Use metadata.url_paths to HTTP Request and export the response to a build folder of HTML.
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'raindown/raindown'
4
+
5
+ module Rain
6
+ class Pages
7
+ include LowType
8
+
9
+ attr_reader :url_paths
10
+
11
+ Result = Struct.new(:metadata, :html)
12
+
13
+ def initialize(metadata:)
14
+ @url_paths = metadata.url_paths
15
+ @raindown = Raindown.new(metadata:)
16
+ end
17
+
18
+ def process(file_path:)
19
+ metadata, markdown = parse_file(file_path:)
20
+ raindown = @raindown.render(markdown:)
21
+
22
+ Result.new(metadata, raindown)
23
+ end
24
+
25
+ private
26
+
27
+ def parse_file(file_path:)
28
+ dash_lines = []
29
+ data_lines = []
30
+ text_lines = []
31
+
32
+ File.foreach(file_path).with_index do |line, index|
33
+ if line.strip == '---' && dash_lines.count < 2
34
+ dash_lines << line
35
+ next
36
+ elsif dash_lines.count > 0 && dash_lines.count < 2
37
+ data_lines << line
38
+ next
39
+ end
40
+
41
+ text_lines << line
42
+ end
43
+
44
+ [YAML.safe_load(data_lines.join, symbolize_names: true), text_lines.join.strip]
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'plugs'
4
+
5
+ module Rain
6
+ class Elements
7
+ include Plugs
8
+
9
+ plug(:toc) do
10
+ plug(:lexeme) do
11
+ require_relative 'lexemes/toc_lexeme'
12
+ TOCLexeme
13
+ end
14
+
15
+ plug(:node) do
16
+ require_relative 'nodes/toc_node'
17
+ TOCNode
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'interfaces/lexeme' # From antlers gem, too generic.
4
+
5
+ module Rain
6
+ module TOCLexeme
7
+ include Antlers::Lexeme
8
+ extend self
9
+
10
+ KEYWORDS = [':toc'].freeze
11
+
12
+ def match?(keywords:, **)
13
+ keywords.keys.include?(':toc')
14
+ end
15
+
16
+ def lexeme(**)
17
+ { toc: :default }
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'antlers'
4
+ require 'nokogiri'
5
+
6
+ module Rain
7
+ class TOCNode < Antlers::LeafNode
8
+ def initialize(name:, template:)
9
+ super(name:)
10
+
11
+ @template = template
12
+ end
13
+
14
+ def render(current_binding: nil, parent_binding: nil, slot_node: nil)
15
+ doc = Nokogiri::HTML(@template)
16
+
17
+ output = <<~HTML
18
+ <div class="floating">
19
+ <details id="toc" open>
20
+ <summary>Table of contents</summary>
21
+ <ul>
22
+ #{doc.css('h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]').map { |h|
23
+ "<li class='#{h.name}'><a href='\##{h['id']}'>#{h.text.strip}</a></li>"
24
+ }.join("\n")}
25
+ </ul>
26
+ </div>
27
+ </details>
28
+ HTML
29
+ end
30
+
31
+ class << self
32
+ def match?(segment:)
33
+ segment[:toc]
34
+ end
35
+
36
+ def build(template:, **)
37
+ new(name: :toc, template:)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'commonmarker'
4
+ require 'antlers/elements'
5
+ require_relative 'elements'
6
+
7
+ module Rain
8
+ class Raindown
9
+ def initialize(metadata: {})
10
+ @metadata = metadata
11
+ end
12
+
13
+ def render(markdown:)
14
+ template = markdown.gsub('<{', '<!-- ANTLERS').gsub('}>', 'ANTLERS -->')
15
+
16
+ doc = Commonmarker.parse(template)
17
+ doc.walk do |node|
18
+ if node.type == :code || node.type == :code_block
19
+ node.string_content = node.string_content.gsub('<!-- ANTLERS', '<{').gsub('ANTLERS -->', '}>')
20
+ end
21
+ end
22
+
23
+ template = doc.to_html(options: { render: { unsafe: true } })
24
+ template = template.gsub('<!-- ANTLERS', '<{').gsub('ANTLERS -->', '}>')
25
+
26
+ return template unless template.include?('<{') || template.include?('{')
27
+
28
+ ast = Antlers.ast(template:, elements: Antlers::Elements[:html, :prop] + Rain::Elements[:toc])
29
+
30
+ Antlers.render(ast:, current_binding: binding)
31
+ end
32
+ end
33
+ end
data/lib/raindeer/boot.rb CHANGED
@@ -6,10 +6,14 @@ require 'low_type'
6
6
  require 'observers'
7
7
  require 'providers'
8
8
 
9
- require_relative '../router/router'
10
- require_relative '../support/config_loader'
9
+ # File paths are relative to the directory where the process is run from, so the app can just require this boot file.
10
+
11
+ #################################################
12
+ # FRAMEWORK INTERNAL API
13
+ #################################################
11
14
 
12
15
  module Rain
16
+ require_relative '../support/config_loader'
13
17
  env = {
14
18
  host: ENV.fetch('RAIN_HOST', nil),
15
19
  port: ENV.fetch('RAIN_PORT', nil),
@@ -18,8 +22,8 @@ module Rain
18
22
  matrix_mode: ConfigLoader.parse_boolean(ENV.fetch('RAIN_MATRIX', nil)),
19
23
  mirror_mode: ConfigLoader.parse_boolean(ENV.fetch('RAIN_MIRROR', nil))
20
24
  }
21
-
22
- config = ConfigLoader.load('config.yaml', env)
25
+ config_path = File.expand_path('config/config.yaml', Dir.pwd)
26
+ config = ConfigLoader.load(config_path, env)
23
27
 
24
28
  Providers.define('rain.router') do
25
29
  require_relative '../router/router'
@@ -37,6 +41,10 @@ module Rain
37
41
  end
38
42
  end
39
43
 
44
+ #################################################
45
+ # FRAMEWORK EXTERNAL API
46
+ #################################################
47
+
40
48
  module Raindeer
41
49
  class << self
42
50
  def router(&block)
@@ -45,5 +53,22 @@ module Raindeer
45
53
  end
46
54
  end
47
55
 
56
+ #################################################
57
+ # APPLICATION CODE
58
+ #################################################
59
+
60
+ require 'antlers' # Adds antlers support to lowload.
48
61
  require 'lowload'
49
62
  LowLoad.dirload(File.expand_path('../system', __dir__))
63
+
64
+ application_path = File.expand_path('app', Dir.pwd)
65
+ return unless Dir.exist?(application_path)
66
+
67
+ metadata = LowLoad.dirload(application_path)
68
+
69
+ if Dir.exist?(File.expand_path('pages', application_path))
70
+ Providers.define('rain.pages', eager: true) do
71
+ require_relative '../pages/pages'
72
+ Rain::Pages.new(metadata:)
73
+ end
74
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'low_node'
4
+ require 'low_type'
5
+ require 'observers'
6
+ require 'providers'
7
+
8
+ # Allows the CLI to load application code and metadata, but not start a server.
9
+
10
+ #################################################
11
+ # FRAMEWORK INTERNAL API
12
+ #################################################
13
+
14
+ module Rain
15
+ Providers.define('rain.router') do
16
+ require_relative '../router/router'
17
+ Router.new
18
+ end
19
+ end
20
+
21
+ #################################################
22
+ # FRAMEWORK EXTERNAL API
23
+ #################################################
24
+
25
+ module Raindeer
26
+ class << self
27
+ def router(&block)
28
+ Providers['rain.router'].instance_eval(&block)
29
+ end
30
+ end
31
+ end
32
+
33
+ #################################################
34
+ # CLI
35
+ #################################################
36
+
37
+ require_relative '../cli/cli'
data/lib/router/router.rb CHANGED
@@ -6,6 +6,7 @@ require 'providers'
6
6
  require_relative 'route'
7
7
  require_relative 'route_event'
8
8
  require_relative 'trie'
9
+ require_relative 'wildcard_route_event'
9
10
 
10
11
  module Rain
11
12
  class Router
@@ -58,9 +59,14 @@ module Rain
58
59
  @trie.match(path: event.request.path.delete_suffix('/')).each do |route_event|
59
60
  response_event = route_event.trigger
60
61
  end
61
-
62
62
  return response_event if response_event
63
63
 
64
+ if @routes['/*']
65
+ route = Route.new(path: event.request.path, verbs: @routes['/*'].verbs)
66
+ wildcard_event = WildcardRouteEvent.trigger(key: '/*', action: :render, route:)
67
+ return wildcard_event if wildcard_event
68
+ end
69
+
64
70
  Low::Events::StatusEvent.trigger(status: Low::Types::Status[404], request: event.request)
65
71
  end
66
72
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'low_event'
4
+
5
+ module Rain
6
+ class WildcardRouteEvent < ::LowEvent
7
+ attr_reader :route, :params
8
+
9
+ def initialize(key:, route:, action: :render)
10
+ super(key:, action:)
11
+
12
+ @route = route
13
+ end
14
+ end
15
+ end
@@ -5,7 +5,7 @@ module System
5
5
  def render(event:)
6
6
  <html>
7
7
  <head>
8
- <link rel="stylesheet" href="/system/pico.min.css">
8
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css">
9
9
  <link rel="stylesheet" href="/system/system.css">
10
10
  </head>
11
11
  <body>
data/lib/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Raindeer
4
- VERSION = '0.5.0'
4
+ VERSION = '0.7.0'
5
5
  end
metadata CHANGED
@@ -1,11 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: raindeer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - maedi
8
- bindir: exe
8
+ bindir: bin
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
@@ -37,6 +37,48 @@ dependencies:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
39
  version: '0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: commonmarker
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: rouge
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: nokogiri
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
40
82
  - !ruby/object:Gem::Dependency
41
83
  name: low_event
42
84
  requirement: !ruby/object:Gem::Requirement
@@ -163,6 +205,20 @@ dependencies:
163
205
  - - ">="
164
206
  - !ruby/object:Gem::Version
165
207
  version: '0'
208
+ - !ruby/object:Gem::Dependency
209
+ name: plugs
210
+ requirement: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - ">="
213
+ - !ruby/object:Gem::Version
214
+ version: '0'
215
+ type: :runtime
216
+ prerelease: false
217
+ version_requirements: !ruby/object:Gem::Requirement
218
+ requirements:
219
+ - - ">="
220
+ - !ruby/object:Gem::Version
221
+ version: '0'
166
222
  - !ruby/object:Gem::Dependency
167
223
  name: providers
168
224
  requirement: !ruby/object:Gem::Requirement
@@ -177,25 +233,39 @@ dependencies:
177
233
  - - ">="
178
234
  - !ruby/object:Gem::Version
179
235
  version: '0'
180
- description: A new Ruby framework. Coming soon...
236
+ description: "Raindeer is an event-driven framework using the dynamic features and
237
+ latest async improvements in Ruby + some weird ideas, \nto build a new breed of
238
+ web application. Each Raindeer component can be used individually in your exisiting
239
+ application, \nor all together as a cohesive framework. Deer to be different.\n"
181
240
  email:
182
241
  - maediprichard@gmail.com
183
- executables: []
242
+ executables:
243
+ - rain
184
244
  extensions: []
185
245
  extra_rdoc_files: []
186
246
  files:
247
+ - bin/rain
248
+ - lib/cli/cli.rb
249
+ - lib/cli/static/static.rb
187
250
  - lib/matrix/cursor.rb
188
251
  - lib/matrix/effects/color_effect.rb
189
252
  - lib/matrix/effects/effect.rb
190
253
  - lib/matrix/effects/leet_effect.rb
191
254
  - lib/matrix/matrix.rb
192
255
  - lib/matrix/stream.rb
256
+ - lib/pages/pages.rb
257
+ - lib/pages/raindown/elements.rb
258
+ - lib/pages/raindown/lexemes/toc_lexeme.rb
259
+ - lib/pages/raindown/nodes/toc_node.rb
260
+ - lib/pages/raindown/raindown.rb
193
261
  - lib/raindeer/boot.rb
262
+ - lib/raindeer/cli.rb
194
263
  - lib/router/route.rb
195
264
  - lib/router/route_event.rb
196
265
  - lib/router/router.rb
197
266
  - lib/router/trie.rb
198
267
  - lib/router/trie_node.rb
268
+ - lib/router/wildcard_route_event.rb
199
269
  - lib/support/config_loader.rb
200
270
  - lib/system/dashboard_node.rbx
201
271
  - lib/system/events_node.rbx
@@ -206,13 +276,14 @@ files:
206
276
  - lib/system/routes_node.rbx
207
277
  - lib/system/status_404_node.rbx
208
278
  - lib/system/status_node.rbx
209
- - lib/system/system.rb
279
+ - lib/system/system_routes.rb
210
280
  - lib/version.rb
211
- homepage: https://codeberg.org/raindeer/raindeer
281
+ homepage: https://github.com/raindeer-rb/raindeer
212
282
  licenses: []
213
283
  metadata:
214
- homepage_uri: https://codeberg.org/raindeer/raindeer
215
- source_code_uri: https://codeberg.org/raindeer/raindeer/src/branch/main
284
+ homepage_uri: https://github.com/raindeer-rb/raindeer
285
+ source_code_uri: https://github.com/raindeer-rb/raindeer/src/branch/main
286
+ mailing_list_uri: https://www.rubyforum.org/tag/raindeer
216
287
  rdoc_options: []
217
288
  require_paths:
218
289
  - lib
@@ -229,5 +300,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
229
300
  requirements: []
230
301
  rubygems_version: 4.0.6
231
302
  specification_version: 4
232
- summary: Deer to be different
303
+ summary: An event-driven and compositional web framework that's easy to use. Deer
304
+ to be different.
233
305
  test_files: []
File without changes